Python技术迷

字节员工吐槽:年薪100万,依然被媳妇挂在网上,被嘲扶贫。。

刚看到个贴子,说字节一个哥们年入百万,被对象在网上吐槽“像扶贫”。

Image

说实话,这事挺扎心的。互联网这几年确实卷,但能干到这个收入,已经是塔尖打工人了。可现实就是这样,有些人永远只看“别人更好”,看不到身边人已经多不容易。

我觉得关键不在钱多少,而在于你身边的人是否懂得尊重你的付出。赚钱的辛苦,不是只有体力活才算苦,脑力透支、情绪透支一样折磨人。

换个角度想吧,别人怎么看不重要,自己过得是否值得才是核心。钱是生活的底气,但不是别人评价你的尺子。真正厉害的人,不被外界眼光牵着走。【备注:文末可领最新资料】

面试题:最大尺寸数组

昨晚十一点多,我在公司楼下便利店等微波炉“叮”的那会儿,手机里我们组小李发来一句:哥,那个“最大尺寸数组”到底是啥意思啊?我一口奶茶差点喷出来…其实就是“最长子数组长度”的事儿,最常见两类:一是和为 k 的最长子数组;二是 0/1 个数相等的最长子数组。思路都绕不开“前缀和 + 哈希表”,别怕,挺顺手的。

先看第一个:给你数组 nums 和整数 k,找出和正好等于 k 的最长连续子数组长度。你们知道吧,暴力会超,n²那种不香。更稳的是前缀和:pre[i] 表示从开头到 i 的总和,如果某段 [j+1..i] 的和是 k,那一定有 pre[i] - pre[j] = k。那就想办法快速找有没有 pre[i]-k 出现过,并且尽量让 j 越靠左越好,这样长度更长。

再一个变体:二元数组里,找 0 和 1 个数一样多的最长子数组。小技巧,把 0 视为 -1,这样“0 和 1 相等”就等价于这段区间的和为 0,直接套上面那套。

代码我用最口水的 Python,别介意有点唠叨:

from typing import List

defmax_len_subarray_sum_k(nums: List[int], k: int) -> int:
    pre = 0
    first_pos = {0: -1}  # 前缀和第一次出现的位置,和为k从0开始要靠它
    ans = 0
for i, x in enumerate(nums):
        pre += x
        need = pre - k
if need in first_pos:
            ans = max(ans, i - first_pos[need])
# 只记录第一次出现的位置,保证区间最长
if pre notin first_pos:
            first_pos[pre] = i
return ans

defmax_len_equal_zeros_ones(nums: List[int]) -> int:
# 把0变-1,问题转成“和为0”的最长子数组
    mapped = [-1if x == 0else1for x in nums]
return max_len_subarray_sum_k(mapped, 0)

# 小测一下
if __name__ == "__main__":
    print(max_len_subarray_sum_k([1, -1, 5, -2, 3], 3))   # 4 -> [1,-1,5,-2]
    print(max_len_subarray_sum_k([-2, -1, 2, 1], 1))      # 2 -> [-1,2]
    print(max_len_equal_zeros_ones([0,1,0,1,1,0,0]))      # 6

这里面有俩细节,别漏了:一个是 first_pos = {0: -1},不这么写你就抓不住从 0 开始那段;另一个是“只在第一次见到某个前缀和时记录下标”,为的是把左端点尽量往前推,区间更长。

复杂度咋样?就是 O(n) 跑完,哈希表均摊 O(1) 查找,空间也是 O(n)。我当时在门口风有点大,奶茶吸管老戳不上…哦对了,有人问负数行不行?能,第一题支持任意整数,因为我们没有滑动窗口那种必须单调的限制,靠的是前缀和配表;但如果你把代码换成双指针,那就只能非负数场景,不要搞混。

再顺嘴提个踩坑:如果数组特别长,Python 里字典不会有问题,但别在循环里频繁 del 或者做不必要的 copy,那样会让你以为算法慢,其实是自己手欠…行了我先去给猫添个粮,等会儿再看小李那个 PR。

-END-

我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html

🔥虎哥私藏精品🔥

虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB,点击下方公众号回复关键字 python 全部免费领