百度面试问到这个,之前虽然做过,但是面试还是表现的不好,所以写下来总结一下。
一:leetcode 1. Two Sum
数组中找两数之和等于0;要求时间复杂度和空间复杂度都是O(N)
使用哈希表来做!
class Solution(object):
def twoSum(self, nums, target):
h = {}
for i, num in enumerate(nums):
n = target - num
if n not in h:
h[num] = i
else:
return [h[n], i]
二:leetcode 15. 3Sum
数组中找出三数之和等于0,并且不能有重复的。
排序+双指针来实现,并且需要去重。
写了好多遍也不一定能快速准确得写好。
时间复杂度O(N^2)
class Solution(object):
def threeSum(self, nums):
if len(nums) < 3: return []
res = []
nums.sort()
n = len(nums)
for i in range(n-2):
if nums[i]>0: break
if i>0 and nums[i]==nums[i-1]: continue # 去重
# 固定nums[i],双指针遍历寻找另外两个数,可能有多个结果
left, right = i+1, n-1
while left < right:
total = nums[i] + nums[left] + nums[right]
if total < 0:
left += 1
elif total > 0:
right -= 1
else:
res.append([nums[i], nums[left], nums[right]])
while left < right and nums[left] == nums[left+1]: # 去重
left += 1
while left < right and nums[right] == nums[right-1]:
right -= 1
left += 1
right -= 1
return res
三:leetcode 16. 3Sum Closest
还是使用排序+双指针来做!
class Solution(object):
def threeSumClosest(self, nums, target):
closed = float('inf') # 绝对值之差
nums.sort()
for k in range(len(nums)-2):
# 只有一个答案,去重单独考虑
i, j = k+1, len(nums)-1
while i < j:
sums = nums[k] + nums[i] + nums[j] # 三数之和
if abs(target - sums) < abs(closed): # 新来的距离更近
closed = target - sums # 更新啊
if closed == 0: # 三数之和刚好等于target,此时就是距离最近的
return sums # 返回的是最近的三数之和,不是diff
if sums < target:
i += 1
else:
j -= 1
return target - closed # 三数之和
四:leetcode 18. 4Sum
和3sum的思路一样,所以从这也可以推导kSum如何来做了!
class Solution(object):
def fourSum(self, nums, target):
if len(nums) < 4: return []
res = []
nums.sort()
for i in range(len(nums)-3):
if i > 0 and nums[i] == nums[i-1]: continue # 优化
for j in range(i+1, len(nums)-2):
if j > i+1 and nums[j] == nums[j-1]: continue # 优化
low, high = j + 1, len(nums) - 1
while low < high:
total = nums[i] + nums[j] + nums[low] + nums[high]
if total > target:
high -= 1
elif total < target:
low += 1
else:
res.append([nums[i], nums[j], nums[low], nums[high]])
while low < high and nums[high] == nums[high-1]: high -= 1
while low < high and nums[low] == nums[low+1]: low += 1
low +=1
high -= 1
return res
五:454. 4Sum II
六:K-sum问题最优时间复杂度能做到O(n^(K-1))复杂度
def fourSum(self, nums, target):
def findNsum(l, r, target, N, result, results):
if r-l+1 < N or N < 2 or target < nums[l]*N or target > nums[r]*N: # early termination
return
if N == 2: # two pointers solve sorted 2-sum problem
while l < r:
s = nums[l] + nums[r]
if s == target:
results.append(result + [nums[l], nums[r]])
l += 1
while l < r and nums[l] == nums[l-1]:
l += 1
elif s < target:
l += 1
else:
r -= 1
else: # recursively reduce N
for i in range(l, r+1):
if i == l or (i > l and nums[i-1] != nums[i]):
findNsum(i+1, r, target-nums[i], N-1, result+[nums[i]], results)
nums.sort()
results = []
findNsum(0, len(nums)-1, target, 4, [], results)
return results