数据结构与算法之双指针(一)

一、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)

posted @ 2020-03-15 17:42  LinBupt  阅读(285)  评论(0编辑  收藏  举报