Python技术迷

突然知道公司涉诈咋办?

今天看到一个网友的吐槽,心情一下子有点沉重

他两年前去香港拿了工签,进入了一家150人左右的公司,做的是云产品开发,听起来还挺正经对吧?可今天,他突然听说公司有个业务线在搞币,涉及到提现过程中收取手续费,套壳涉诈,搞得他有点崩溃。更夸张的是,听说一位team leader因为这个事被上门带走,取保候审了。简直是电影情节,我都替他捏把汗。

Image

他现在面临的困境是——他自己没参与到这个“涉诈”业务,也没接触过相关工作,甚至工资没涨,奖金也没啥,但是如果真要追溯的话,自己会不会也受到波及?

我觉得这个问题其实挺有现实意义的。不过,如果这件事真的牵涉到公司整体的法律问题,能不能“躲得过”就得看具体情况了。

要说风险,我觉得只要自己没有直接参与那些涉及违法的操作,且完全不知情,风险确实不大。

Image

但公司如果真的被查到,这事也不是完全没有连带责任的可能,尤其是在一些法律法规严苛的地方。

所以我觉得最好的办法,还是做好准备,尽量把自己撇得清清楚楚的,早点“润”也是个好选择。【备注:文末可领最新资料】

算法题:最大加号标志

今天我们来聊聊一个算法题:最大加号标志。

题目大概是这样的:

你给定一个由 1 和 0 组成的矩阵(二维数组),要求你找到其中能形成最大“加号”标志的面积。具体来说,加号标志由一个中心点和它向四个方向(上、下、左、右)延伸的臂组成。每个臂的长度必须至少为 1,并且中心点及其四个臂上的所有元素必须是 1。

这道题的关键就是如何高效地找到每个点作为中心时能够扩展到的最大臂长。

我一开始看这个题目就觉得,呃,直觉上感觉应该是 O(n^2) 复杂度,甚至可能更高,毕竟你得对每个点做个遍历,对吧?但是!我告诉你,思路一出来,就觉得这个问题能有更聪明的解法。🌟

思路分析

首先,咱们假设矩阵的大小是 m x n,然后核心任务是对每个点计算它可以扩展到的“臂长”,也就是这个点能否成为某个加号的中心,并且能形成多大的加号。

你可以从四个方向出发——上、下、左、右,分别计算每个点在这四个方向上能延伸的最大长度。

这个计算可以借助动态规划来优化。具体来说,我们可以为矩阵中每个位置维护四个数组(分别记录上、下、左、右方向上的最大连续 1 的长度)。有了这些信息,我们就能轻松计算出每个点作为中心时能形成的最大加号大小。

步骤

  1. 计算每个点四个方向的延伸长度
    我们从矩阵的四个方向分别计算每个点可以延伸到的最大长度。首先从上到下扫描,记录每个点向上延伸的最大连续 1 的个数;然后从下到上扫描,记录每个点向下延伸的最大连续 1 的个数。接着从左到右扫描,记录每个点向左延伸的最大连续 1 的个数;最后从右到左扫描,记录每个点向右延伸的最大连续 1 的个数。

  2. 计算加号的面积
    对于每个点来说,它能形成的最大加号的臂长是它四个方向延伸长度的最小值。因为如果一个方向的延伸长度比较短,整个加号的大小就会受到限制。所以最小的延伸值就是这个点能够作为加号中心的最大半径。

  3. 求最大面积
    通过遍历矩阵中的每一个点,计算它可以形成的加号面积(面积 = 2 * arm_length - 1),记录下最大的那个。

代码实现

下面是我写的代码:

def orderOfLargestPlusSign(N, mines):
    # Step 1: Initialize dp tables for four directions
    left = [[0] * N for _ in range(N)]
    right = [[0] * N for _ in range(N)]
    up = [[0] * N for _ in range(N)]
    down = [[0] * N for _ in range(N)]

    # Step 2: Mark mines
    for r, c in mines:
        left[r][c] = right[r][c] = up[r][c] = down[r][c] = -1

    # Step 3: Fill the dp tables
    for r in range(N):
        for c in range(N):
            if left[r][c] != -1:
                left[r][c] = left[r][c-1] + 1 if c > 0 else 1 if left[r][c] != -1 else 0
            if up[r][c] != -1:
                up[r][c] = up[r-1][c] + 1 if r > 0 else 1 if up[r][c] != -1 else 0
    for r in range(N-1, -1, -1):
        for c in range(N-1, -1, -1):
            if right[r][c] != -1:
                right[r][c] = right[r][c+1] + 1 if c < N-1 else 1 if right[r][c] != -1 else 0
            if down[r][c] != -1:
                down[r][c] = down[r+1][c] + 1 if r < N-1 else 1 if down[r][c] != -1 else 0

    # Step 4: Find the largest plus sign
    max_arm = 0
    for r in range(N):
        for c in range(N):
            if left[r][c] != -1:
                arm_length = min(left[r][c], right[r][c], up[r][c], down[r][c])
                max_arm = max(max_arm, arm_length)

    # Step 5: Return the maximum area
    return max_arm * max_arm

# Example usage:
N = 5
mines = [(4, 2)]
print(orderOfLargestPlusSign(N, mines))  # Output: 2

解析

首先,我们初始化了四个二维数组 left、right、up、down,它们分别记录每个点在四个方向上延伸的最大长度。如果遇到地雷(即 mines 中的点),就直接把这些位置的值设置为 -1,表示不能通过这些点。然后,我们从上到下、从左到右,再从下到上、从右到左依次填充这些方向上的最大延伸长度。

最后,我们遍历整个矩阵,找出每个点能作为加号中心的最大半径,并计算出对应的面积。最终返回最大的面积。

性能

这个解法的时间复杂度是 O(N^2),其中 N 是矩阵的大小。由于每个位置只需要经过常数次操作,因此效率是可以接受的。

对编程、职场感兴趣的同学,大家可以联系我微信:golang404,拉你进入“程序员交流群”。
🔥虎哥私藏精品 热门推荐🔥

虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》。

资料包含了《IDEA视频教程》、《最全python面试题库》、《最全项目实战源码及视频》及《毕业设计系统源码》,总量高达650GB,全部免费领取。