Leetcode题解 - 双指针求n数之和

1. 两数之和

"""
双指针,题目需要返回下标,所以记录一个数字对应的下标
"""
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        r = [[ind, num] for ind, num in enumerate(nums)]
        r = sorted(r, key=lambda x: x[1])
        head = 0
        tail = len(r) - 1
        while head < tail:
            s = r[head][1] + r[tail][1]
            if s == target:
                return [r[head][0], r[tail][0]]
            elif s > target:
                tail -= 1
                # 跳过重复值,去重的规则都一样(下面的也是这样)
                while head < tail and r[tail][1] == r[tail+1][1]:
                    tail -= 1

            else:
                head += 1
                while head < tail and r[head][1] == r[head-1][1]:
                    head += 1

15. 三数之和

"""
双指针,所以先固定一个数字,用双指针来找到另外两个数字。注意记得剪枝,否则一定会超时的。(被超时操控的恐惧...
"""
class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        nums.sort()
        vis = set()
        res = []
        for i in range(len(nums)):
            if nums[i] in vis:
                continue
            if nums[i] > 0:
                break
            vis.add(nums[i])
            head = i + 1
            tail = len(nums) - 1
            while head < tail and head < len(nums) and tail < len(nums):
                s = nums[i] + nums[head] + nums[tail]
                if not s:
                    res.append([nums[i], nums[head], nums[tail]])
                    head += 1
                    tail -= 1
                    # 跳过重复元素
                    while head < tail and nums[head] == nums[head - 1]:
                        head += 1
                    while head < tail and nums[tail] == nums[tail + 1]:
                        tail -= 1
                if s > 0:
                    tail -= 1
                    while head < tail and nums[tail] == nums[tail + 1]:
                        tail -= 1
                if s < 0:
                    head += 1
                    while head < tail and nums[head] == nums[head - 1]:
                        head += 1
        return res


18. 四数之和

"""
固定两个,双指针找另外两个
"""
class Solution:
    def fourSum(self, nums, target):
        nums.sort()
        res = []
        for i in range(len(nums)):
            for j in range(i+1, len(nums)):
                head = j + 1
                tail = len(nums) - 1
                while head < tail:
                    s = nums[i] + nums[j] + nums[head] + nums[tail]
                    if s == target:
                        res.append([nums[i], nums[j], nums[head], nums[tail]])
                        head += 1
                        tail -= 1
                        while head < tail and nums[head] == nums[head - 1]:
                            head += 1
                        while head < tail and nums[tail] == nums[tail + 1]:
                            tail -= 1
                    elif s > target:
                        tail -= 1
                        while head < tail and nums[tail] == nums[tail + 1]:
                            tail -= 1
                    else:
                        head += 1
                        while head < tail and nums[head] == nums[head - 1]:
                            head += 1
        return list(set([tuple(i) for i in res]))

总结

可以看到,无论是2、3or4,都是固定除了双指针之外的元素,再用双指针去找剩下的元素,代码几乎没有改变,切记要记得剪枝。

posted @ 2019-12-22 15:23  但是我拒绝  阅读(490)  评论(1编辑  收藏  举报