北大硕士LeetCode算法专题课-查找相关问题

黑马算法面试专题

北大硕士LeetCode算法专题课-字符串相关问题         北大硕士LeetCode算法专题课-数组相关问题_​​​​​​
 

北大硕士LeetCode算法专题课-基础算法查找_

北大硕士LeetCode算法专题课-基础算法之排序_客

北大硕士LeetCode算法专题课---算法复杂度介绍_客

查找相关问

查找有无:

某个 元素是否存在 通过集合set 可以解决这一类问题

查找对应关系:

某个元素出现了几次, 返回满足条件元素的下标, 通过字典 Dict)可以解决这一类问题

查找问题中经常要用到集合与字典, 要熟悉相关API

 

 两个数组的交集 (LeetCode349)

给定两个数组 nums1 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序

 

时间复杂度O(mlogm+nlog

def intersection(nums1, nums2):  nums1.sort()
nums2.sort()
length1, length2 = len(nums1), len(nums2)  intersection = list()
index1 = index2 = 0
while index1 < length1 and index2 < length2:  num1 = nums1[index1]
num2 = nums2[index2]
if num1 == num2:
if not intersection or num1 != intersection[-1]:  intersection.append(num1) # 保证加入元素的唯一性
index1 += 1
index2 += 1
elif num1 < num2:  index1 += 1
else:
index2 += 1
return intersection

 思路二:利用set

def intersection( nums1, nums2):  """
:type nums1: List[int]
:type nums2: List[int]
:rtype: List[int]  """
set1 = set(nums1)  set2 = set(nums2)
if len(set2)> len(set1):
return [x for x in set1 if x in set2]
else:
return [x for x in set2 if x in set1]

 时间复杂度:O(m+n)

两个数组的交集 II(LeetCode350)

给你两个整数数组 nums1 nums2 ,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,

应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值)。可以不考虑输出结果的顺序

def intersect(nums1, nums2):  nums1.sort()  nums2.sort()

length1, length2 = len(nums1), len(nums2)  intersection = list()
index1 = index2 = 0
while index1 < length1 and index2 < length2:
if nums1[index1] < nums2[index2]:  index1 += 1
elif nums1[index1] > nums2[index2]:  index2 += 1
else:
intersection.append(nums1[index1])  index1 += 1
index2 += 1

return intersection

两个数组的交集 II(LeetCode350)  

思路二:利用字典

def intersect2(nums1, nums2):
if len(nums1) > len(nums2):
return intersect2(nums2, nums1)

m = collections.Counter()
for num in nums1:  m[num] += 1

intersection = list()
for num in nums2:
if m.get(num, 0) > 0:  intersection.append(num)  m[num] -= 1
if m[num] == 0:  m.pop(num)

return intersection

复杂度分析

时间复杂度:O(m+n),其中 m 和 n 分别是两个数组的长度

空间复杂度:O(min(m,n)),其中 m n 分别是两个数组的长度

同构字符串 (LeetCode205)

给定两个字符串 s t ,判断它们是否同构。如果 s 中的字符可以按某种映射关系替换得到 t ,那么这两个字符串是同构的。 每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序。不同字符不能映射到同一个字符上,相同字符只能映 射到同一个字符上,字符可以映射到自己本身。

 使用字典构建查找表

def isIsomorphic(s, t):
if len(t) != len(s):
return False  dict_s = {}  dict_t = {}
for i in range(len(s)):
s_char, t_char = s[i], t[i]
if s_char not in dict_s:  dict_s[s_char] = t_char
if t_char not in dict_t:  dict_t[t_char] = s_char
if dict_s[s_char] != t_char or dict_t[t_char] != s_char:
return False
return True

 度分析时间复杂度:O(n)

两数之和 (LeetCode 1)

给定一个整数数组nums和一个整数目标值target请你在该数组中找出和为目标值 target那两个整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

两数之和 (LeetCode 1)

解法一 暴力解法 双重for循环O(N2

解法二:使用查找表(dict),可以将寻找 target - x 的时间复杂度降低到从 O(N) 降低到 O(1)。

创建一个字典,对于每一个 x,首先查询字典中是否存在 target - x,然后将 x 插入到字典中,即可保证不会让 x  和自己匹配。

def twoSum(nums, target):  hashtable = dict()
for i, num in enumerate(nums):
if target - num in hashtable:
return [hashtable[target - num], i]  hashtable[nums[i]] = i
return []

 复杂度分析时间复杂度:时间复杂度:O(N),其中 N是数组中的元素数量。Python dict 查找时间复杂度O(1)  空间复杂度:O(N)

四数相加 II (LeetCode454)

给你四个整数数组 nums1nums2nums3 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足:

0 <= i, j, k, l < n

nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0

示例 1

输入:nums1 = [1,2], nums2 = [-2,-1], nums3 = [-1,2], nums4 = [0,2]

输出:提示 1 <= n <= 200

解释:

1.  (0, 0, 0, 1) -> nums1[0] + nums2[0] + nums3[0] + nums4[1] = 1 + (-2) + (-1) + 2 = 0

2.  (1, 1, 0, 0) -> nums1[1] + nums2[1] + nums3[0] + nums4[0] = 2 + (-1) + (-1) + 0 = 0

将四个数组分成两部分,A B 为一组,C D 为另外一组。

对于 A B,我们使用二重循环对它们进行遍历,得到所有 A[i]+B[j] 的值并存入哈希映射中。对于哈希映射中的每个键值对,每 个键表示一种 A[i]+B[j],对应的值为 A[i]+B[j]出现的次数。

对于 C D,我们同样使用二重循环对它们进行遍历。当遍历到 C[k]+D[l] 时,如果 -(C[k]+D[l]) 出现在哈希映射中,那么将 -  (C[k]+D[l]) 对应的值累加进答案中。

最终即可得到满足 A[i]+B[j]+C[k]+D[l]=0=的四元组数目。

复杂度分析:时间复杂度:O(n2)     空间复杂度:O(n2)

def fourSumCount(A, B, C, D):
countAB = collections.Counter(u + v for u in A for v in B)  ans = 0
for u in C:
for v in D:
if -u - v in countAB:
ans += countAB[-u - v]
return ans

存在重复元素 II (LeetCode 219)

给你一个整数数组nums和一个整数 k ,判断数组中是否存在两个不同的索引 i j ,满足nums[i] == nums[j] abs(i - j) <= k 。 如果存在,返回 true ;否则,返回 false

 解法1 创建字典用于查找,遍历的过程中,判断在字典中是否存在满足条件的key如果满足直接返回True如不满足,则将数 组中元素不断放入字典中, key为数值, value为索引

def containsNearbyDuplicate(nums, k):  pos = {}
for i, num in enumerate(nums):
if num in pos and i - pos[num] <= k:
return True  pos[num] = i
return False

解法2 滑动窗口, 创建一个set 用来保存窗口中数据, 当扩大窗口时, 如果从set中能取到新加入的值, 说明有满足条件的元素

 

 

 

解法2 滑动窗口

def containsNearbyDuplicate2(nums, k):  s = set()
for i, num in enumerate(nums):
if i > k:
s.remove(nums[i - k - 1])
if num in s:
return True  s.add(num)
return False

 复杂度分析时间复杂度:O(n) 空间复杂度:O(n)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值