Python技术迷

以前大家都担心被公司裁员,现在就不一样了!似乎只要公司愿意支付N+1,立马就有一堆员工自告奋勇,令人不解!

刚看到个贴子,说现在公司一提裁员,反倒是一堆人排着队等着拿 N+1

Image

我觉得这事吧,说到底反映了一个现实:大家不是不想上班,是不想“亏着”上班。

但本质还是性价比——付出和回报不对等,谁还愿意硬撑?和超市打折一样,折扣够大,大家自然抢得欢。

换个角度想,员工愿意被裁,也是一种无声的反馈:环境不行、预期不行、希望看不到。与其日复一日被耗着,不如体面拿钱走人。只是有些网友调侃“裁我我谢谢你”,这话听着好笑,但背后多少有点无奈。【备注:文末可领最新资料】

面试题:存在重复元素

“存在重复元素”这个题,大概就一句话:

给你一个整数数组 nums,判断里面是不是有相同的元素,有就返回 True,没有就返回 False。

比如:

  • [1,2,3,1] → 有两个 1 → True
  • [1,2,3,4] → 都不一样 → False
  • [1,1,1,3,3,4,3,2,4,2] → 一堆重复 → True

听起来很简单,但这是面试里经常拿来考你时间复杂度和空间换时间的小题。

最直接的想法:两层循环硬比

如果不考虑复杂度,最“暴力”的写法就是: 每个元素都跟后面的每个元素比一遍,只要发现一样的,就说“有重复”。

伪代码脑补一下: 外层选一个数,内层在它后面找有没有和它一样的。

Python 写出来是这样:

defcontains_duplicate(nums):
    n = len(nums)
for i in range(n):
for j in range(i + 1, n):
if nums[i] == nums[j]:
returnTrue
returnFalse

复杂度很明显:

  • 时间:两层循环,最坏要比 n*(n-1)/2 次,约等于 O(n^2)
  • 空间:只用了一点循环变量,O(1)

缺点也很明显:数据一大就嘎嘎慢,上万、几十万数据时基本跑不动,面试一般不会满意这个答案,只能算你“会做题,但不会优化”。

先排序再扫一遍

再往前想一步: 数组里如果有重复元素,那排完序之后,相同的元素一定挨在一起。

那我们就可以:

  1. 先把数组排序;
  2. 然后从头到尾扫一遍,只要发现 nums[i] == nums[i-1],说明有重复。

代码很简单:

defcontains_duplicate(nums):
    nums.sort()  # 原地排序
for i in range(1, len(nums)):
if nums[i] == nums[i - 1]:
returnTrue
returnFalse

复杂度:

  • 排序:O(n log n)
  • 扫一遍:O(n)
  • 总体:O(n log n)
  • 空间:如果用的是原地排序,额外空间可以认为是 O(1)(忽略底层实现的小开销)

这个方案已经比暴力好多了,能过大部分面试和题目。但如果面试官继续追问:“还能更快吗?有没有 O(n) 的办法?”那就轮到哈希表登场了。

用 set 记录出现过的数

核心想法特别简单:

一边遍历数组,一边用一个 set 记录已经见过的数字。 每来一个新数字:

  • 如果它不在 set 里,就加进去;
  • 如果它已经在 set 里,说明重复了,直接返回 True。

Python 版本:

defcontains_duplicate(nums):
    seen = set()
for x in nums:
if x in seen:
returnTrue
        seen.add(x)
returnFalse

复杂度分析:

  • 时间:遍历一遍数组是 O(n),set 的查找和插入平均是 O(1),所以整体是 平均 O(n)
  • 空间:set 里最坏要装下所有元素 → O(n)

这个就是面试官最想听到的那种:用空间换时间 的解法,思路也非常常见: “判断有没有重复” → 立刻想到 set 或者哈希表。

再顺便多说两句变种题

这个题的基础想法搞懂之后,很多变种都能顺着写出来,比如:

  1. 返回所有重复的元素有哪些

  • 可以多准备一个 duplicates 集合,遇到第二次出现的就加进去。
  • 返回第一个出现重复的数

    • 跟上面的哈希解法一样,一旦发现 x in seen,除了返回 True,也可以直接返回这个 x。
  • 判断是否存在出现次数大于等于 k 的元素

    • 可以用 dict 或 collections.Counter 统计次数,再看有没有 count >= k 的。

    这些其实都是同一类思路:用额外的数据结构记住“我已经知道的信息”,避免重复工作。

    这道“存在重复元素”:

    • 暴力双循环:能做,但太慢 O(n^2)
    • 排序再遍历:O(n log n),不占额外空间,已经不错
    • set / 哈希表:时间 O(n),空间 O(n),面试首选

    如果你在用 Python 刷题,这一类“判断有没有重复”,习惯性先想一句:

    len(nums) != len(set(nums))

    这行甚至就是完整答案(虽然不太适合考察思路的场景),但写业务代码时是真香。

    -END-

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

    🔥虎哥私藏精品🔥

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