leetcode 1.两数之和
# 暴力法(时间复杂度:O(n^2), 空间复杂度:O(1))
class Solution(object):
def twoSum(self, nums, target):
n = len(nums)
for i in range(n-1):
for j in range(i+1, n):
if nums[i]+nums[j]==target:
return [i, j]
return []
# 求解
s = Solution()
s.twoSum([2,7,11,15], 9)
# return
[0, 1]
# 哈希表(时间复杂度:O(n), 空间复杂度:O(n))
class Solution(object):
def twoSum(self, nums, target):
hashmap = {}
for idx, num in enumerate(nums):
if target-num in hashmap:
return [hashmap[target-num], idx]
else:
hashmap[num] = idx
return []
# 求解
s = Solution()
s.twoSum([2,7,11,15], 9)
# return
[0, 1]
class Solution(object):
def twoSum(self, nums, target):
if not nums: return []
left, right = 0, len(nums)-1
while left<right:
total = nums[left] + nums[right]
if total<target:
left += 1
elif total>target:
right -= 1
else:
return [left+1, right+1]
# 求解
s = Solution()
s.twoSum([2, 7, 11, 15], 9)
# return
[1, 2]
leetcode 15.三数之和
# 双指针法
class Solution(object):
def threeSum(self, nums):
if not nums: return []
res = []
nums.sort()
n = len(nums)
for i in range(n):
if nums[i]>0: break
if i>0 and nums[i]==nums[i-1]: continue
j = i+1
k = n-1
while j<k:
if nums[j]+nums[k]+nums[i]==0:
res.append([nums[i], nums[j], nums[k]])
while j<k and nums[j]==nums[j+1]: j+=1
while j<k and nums[k]==nums[k-1]: k-=1
j+=1
k-=1
elif nums[j]+nums[k]+nums[i]<0:
j+=1
else:
k-=1
return res
# 求解
s = Solution()
s.threeSum([-1,0,1,2,-1,-4])
# return
[[-1,-1,2],[-1,0,1]]
# 双指针法
class Solution(object):
def threeSumClosest(self, nums, target):
if not nums: return []
nums.sort()
n = len(nums)
res = sum(nums[:3])
for i in range(n):
j = i+1
k = n-1
while j<k:
s = nums[i]+nums[j]+nums[k]
if abs(res-target)>abs(s-target):
res = s
elif s>target:
k-=1
else:
j+=1
return res
# 求解
s = Solution()
s.threeSumClosest([-1,2,1,-4], 1)
# return
2
leetcode 18.四数之和
# 双指针法
class Solution(object):
def fourSum(self, nums, target):
if not nums: return []
if nums==[0,0,0,0] and target==0: return [nums]
nums.sort()
n = len(nums)
res = []
for i in range(n-3):
if i>0 and nums[i]==nums[i-1]: continue
if nums[i]+nums[i+1]+nums[i+2]+nums[i+3]>target: break
if nums[i]+nums[n-3]+nums[n-2]+nums[n-1]<target: continue
for j in range(i+1, n-2):
if j>i+1 and nums[j]==nums[j-1]: continue # 此处必须是j>i+1而非j>i(j>i可能会跳过i与j相同时的情况,nums=[-1,0,1,2,-1,-4] target=-1时会跳过[-1,-1,0,1]这个解)
if nums[i]+nums[j]+nums[j+1]+nums[j+2]>target: break
if nums[i]+nums[j]+nums[n-2]+nums[n-1]<target: continue
left, right = j+1, n-1
while left<right:
if nums[i]+nums[j]+nums[left]+nums[right]==target:
res.append([nums[i], nums[j], 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
elif nums[i]+nums[j]+nums[left]+nums[right]<target:
left+=1
else:
right-=1
return res
# 求解
s = Solution()
s.fourSum([1,0,-1,0,-2,2], 0)
# return
[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]