数据结构与算法之双指针(一)
一、Reverse
本质: i j交换元素
1 def reverse(nums): 2 n = len(nums) 3 for i in range(n//2): 4 nums[i], nums[n-i-1] = nums[n-i-1], nums[i] 5 return nums 6 nums = [1, 2] 7 print(reverse(nums))
1 def reverse(nums): 2 i = 0 3 j = len(nums) - 1 4 while i <= j: 5 nums[i], nums[j] = nums[j], nums[i] 6 i += 1 7 j -= 1 8 return nums 9 nums = [1, 2, 3] 10 print(reverse(nums))
二、TwoSum
Given an array of integers, find two numbers such that they add up to a specific target number.
1 # 无序数组-->dict O(n) O(n) 2 def two_sum(nums, target): 3 dic = {} 4 for ind, num in enumerate(nums): 5 if num in dic: 6 return [dic[num], ind] 7 else: 8 dic[target - num] = ind
1 # 有序数组-->双指针 如果无序O(nlogn+n) O(1) 2 def two_sum2(nums, target): 3 i = 0 4 j = len(nums) - 1 5 while i < j: 6 if nums[i] + nums[j] > target: 7 j -= 1 8 elif nums[i] + nums[j] == target: 9 return (nums[i], nums[j]) 10 else: 11 i += 1
扩展:LeetCode532.数组中的K-diff对
给定一个整数数组和一个整数 k, 你需要在数组里找到不同的 k-diff 数对。这里将 k-diff 数对定义为一个整数对 (i, j), 其中 i 和 j 都是数组中的数字,且两数之差的绝对值是 k.
1 class Solution: 2 def findPairs(self, nums: List[int], k: int) -> int: 3 if k < 0: 4 return 0 5 ans, diff = set(), set() 6 for num in nums: 7 if num - k in ans: 8 diff.add(num-k) 9 if k + num in ans: 10 diff.add(num) 11 ans.add(num) 12 return len(diff)
1 class Solution: 2 def findPairs(self, nums: List[int], k: int) -> int: 3 if k < 0: 4 return 0 5 ans, diff = set(), set() 6 for num in nums: 7 if num - k in ans: 8 diff.add(num) 9 if k + num in ans: 10 diff.add(num+k) 11 ans.add(num) 12 return len(diff)
三、Three Sum
Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
# O(n**2) def three_sum(nums, target): res = [] nums.sort() for i in range(len(nums) - 2): if i > 0 and nums[i] == nums[i-1]: continue j, k = i + 1, len(nums) - 1 while j < k: s = nums[i] + nums[j] + nums[k] if s < target: j += 1 elif s > target: k -= 1 else: 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 return res nums = [-1, 0, 1, 2, -1, -4, 2, -1, 2] print(three_sum(nums))
四、Four Sum
1 def four_sum(nums, target): #O(n**3) 2 nums.sort() 3 res = [] 4 for i in range(len(nums)): 5 if i > 0 and nums[i] == nums[i-1]: 6 continue 7 for j in range(i + 1, len(nums)): 8 if j > i + 1 and nums[j] == nums[j - 1]: 9 continue 10 l = j + 1 11 r = len(nums) - 1 12 while l < r: 13 sum = nums[i] + nums[j] + nums[l] + nums[r] 14 if sum > target: 15 r -= 1 16 elif sum < target: 17 l += 1 18 elif l > j + 1 and nums[l] == nums[l-1]: 19 l += 1 20 elif r < len(nums) - 1 and nums[r] == nums[r + 1]: 21 r -= 1 22 else: 23 res.append([nums[i], nums[j], nums[l], nums[r]]) 24 l += 1 25 r -= 1 26 return res 27 nums = [-1, 0, 1, 2, -1, -4, 2, -1, 2] 28 print(four_sum(nums, 0))
1 # O(n**2) 2 def three_sum(nums, target): 3 res = [] 4 nums.sort() 5 for i in range(len(nums) - 2): 6 if i > 0 and nums[i] == nums[i-1]: 7 continue 8 j, k = i + 1, len(nums) - 1 9 while j < k: 10 s = nums[i] + nums[j] + nums[k] 11 if s < target: 12 j += 1 13 elif s > target: 14 k -= 1 15 else: 16 res.append((nums[i], nums[j], nums[k])) 17 while j < k and nums[j] == nums[j + 1]: 18 j += 1 19 while j < k and nums[k] == nums[k - 1]: 20 k -= 1 21 j += 1 22 k -= 1 23 return res 24 25 nums = [-1, 0, 1, 2, -1, -4, 2, -1, 2] 26 print(three_sum(nums, 0))
五、K Sum
递归-->subset O(2**n)