Python技术迷

迪子员工爆料:老员工的学历和能力都堪忧啊,三本野鸡大学毕业,还管理一堆985,211硕士,华为腾讯的下属。。

最近刷到一条猛料:迪子员工爆料,说他们公司那些老员工不仅学历堪忧,还是三本毕业,居然还能管理一堆985、211的高材生!甚至还有从华为、腾讯挖过来的下属。

网友直接炸锅了:这不合理啊,凭什么呀?

Image

作为程序员,我第一反应是:学历重要,但不等于能力啊!那些三本毕业的老员工,搞不好是靠硬核技术和经验撑起来的。
如果人家技术栈够硬,带团队还靠谱,管理着一群高学历下属,也没啥毛病啊。💻  
但换个角度,我也能理解有些高学历员工的不平衡心理:自己辛辛苦苦卷进了名校,结果还得听一个三本“学长”指挥。
问题是,职场看的是你怎么解决问题,而不是你毕业证上的Logo。那些老员工可能没咱们卷学历,但人家年薪37万靠的绝对不只是运气。
当然啦,也不排除个别“靠关系混上去”的情况,但作为码农,我更愿意相信“技术不分学历”。所以与其吐槽,还不如先看看自己有没有真本事被人认可。

算法题:区间和的个数

聊一个算法题,名字叫“区间和的个数”。一听这个题目,我脑袋里立刻冒出了两个字:折磨。别问,问就是刷题 PTSD 上线了。

题目背景

先简单说下问题,题目是这样的:给定一个整数数组 nums 和两个整数 lower 和 upper,找到数组中所有区间和(也就是从数组中某一段连续子数组的和)的个数,要求区间和在 [lower, upper] 之间。
比如说,nums = [-2, 5, -1],lower = -2,upper = 2。结果是 3,因为满足条件的区间有:
  • [-2]
  • [-2, 5, -1]
  • [5, -1]
这题你要是暴力解的话,直接写双层循环,时间复杂度是 (O(n^2)),轻轻松松炸掉服务器。要是在面试的时候来这一手,面试官估计直接跟你说:“感谢您的时间,我们会通知您的。”😅

解法优化

所以,我们得想办法优化。稍微有点算法基础的同学可能会想到:这不就是个 前缀和 的变种问题嘛?

用前缀和 + 二分查找

前缀和的核心思想是,用一个数组存储从数组开头到每个位置的累计和。通过计算两段前缀和的差值,我们可以快速获得任意区间的和。
不过直接用前缀和还不够快,我们需要一个更高效的办法来查询区间和是否在 [lower, upper] 之间。这里我们可以用 二分查找 或者 归并排序,两个方法都很有意思。

归并排序解法

归并排序本身是用来排序的,但我们稍微改造一下它,就可以在合并的过程中高效计算满足条件的区间和。
def countRangeSum(nums, lower, upper):
    def merge_sort(start, end):
        if start >= end:
            return 0
        mid = (start + end) // 2
        count = merge_sort(start, mid) + merge_sort(mid + 1, end)

                # 统计区间和的个数
        j, k, t = mid + 1, mid + 1, mid + 1
        temp = []
        for i in range(start, mid + 1):
            while k <= end and prefix_sum[k] - prefix_sum[i] < lower:
                k += 1
            while j <= end and prefix_sum[j] - prefix_sum[i] <= upper:
                j += 1
            count += j - k

                        # 归并过程
            while t <= end and prefix_sum[t] < prefix_sum[i]:
                temp.append(prefix_sum[t])
                t += 1
            temp.append(prefix_sum[i])
        temp.extend(prefix_sum[t:end + 1])
        prefix_sum[start:end + 1] = temp

                return count

    # 计算前缀和
    prefix_sum = [0]
    for num in nums:
        prefix_sum.append(prefix_sum[-1] + num)

        return merge_sort(0, len(prefix_sum) - 1)

# 示例运行
nums = [-2, 5, -1]
lower = -2
upper = 2
print(countRangeSum(nums, lower, upper))  # 输出:3

写完之后再想想,一段代码搞定排序和统计,还是挺优雅的。只不过在面试的时候,写这个归并排序的改造代码,怕是手抖错一个缩进就凉了。
归并排序的时间复杂度是 (O(n \log n)),对比暴力解的 (O(n^2)),性能提升巨大。这个优化方法可以说是面试官的心头好,但也别掉以轻心,归并排序代码实现起来有点绕,多练练才不至于当场翻车。
对编程、职场感兴趣的同学,大家可以联系我微信:golang404,拉你进入“程序员交流群”。
🔥虎哥私藏精品 热门推荐🔥

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

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