三数之和

17 篇文章 0 订阅
5 篇文章 0 订阅

三数之和

三数之和
这道题和

三道题思路一样,都可以用双指针的方式和hash表的方式进行优化。
当数字个数越多hash的方式优势越明显,四数之和明显优于双指针
点:如何去掉重复的数据即不包含重复的三元组

双指针

固定一个数据寻找另外两个数据就退化为了两数之和
每次加入元素的时候比较其与相邻元素的关系如果相等就跳过这个元素(去重)
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        // hash
        // 回顾两数之和,给定一个k求解两个数之和为k
        // 用O(n)时间构建一个map,key为当前值,value为所需值
        // O(n)时间构造字典key - value (key + value == 0)
        // 双指针循环
        // 重复数据
        int len = nums.size(); 
        if(len < 3) return {};
        sort(nums.begin(), nums.end());
        vector<vector<int>> rst = {};
        int tag = 0;
        for(int i=0; i<len;++i){
            if(nums[i]>0) return rst;
            if(i>0 && (nums[i] == nums[i-1])) continue;
            int low = i+1; //
            int high = len-1;
            tag = 0 - nums[i]; 
            while(low<high){
                if(nums[low] + nums[high] == tag) {
                    rst.push_back({nums[i], nums[low], nums[high]});
                    while(low < high && nums[low] == nums[low+1]) ++low;//去重
                    while(low < high && nums[high] == nums[high-1]) --high;
                    ++low;
                    --high;
                }
                else if(nums[low] + nums[high] > tag) --high;
                else ++low;
            }
        }
        return rst;
    }
};

hash

LeetCode-探索卡片
三数之和和四数之和,探索卡片里有非常好的解释

以三数之和为例子
三数之和相对于二数之和就是,我确定一个数sum 那么就用二数之和找到这个 k - sum就可以了
四数之和同理
仍要注意去重(相同continue跳过)

python代码如下

class Solution:

    def twoSum(self, nums, target, l, r):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """

        n = len(nums[l : r+1])
        if n < 2:
            return list()

        start = nums[l - 1]
        dict1 = dict()
        ret = list()
        for i in range(l, r+1):
            other = target - nums[i]
            if other in dict1:
                ret.append([start, other, nums[i]])
            dict1[nums[i]] = i

        return ret

    # nums[l...r] 中返回 a+b+c=target
    def threeSum(self, nums, target, l, r):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """

        n = len(nums[l : r+1])
        if n < 3:
            return list()

        start = nums[l-1]
        ret = list()
        for i in range(l, r+1):
            if nums[i] > 0 and target <= 0:
                break
            if (i >= l+1 and nums[i] == nums[i-1]):
                continue
            ll = self.twoSum(nums, target-nums[i], i+1, r)
            if (ll == list()):
                continue
            for i in ll:
                i.insert(0, start)
                ret.append(i)
        return ret

    def fourSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
        n = len(nums)
        if n < 4:
            return []
        nums.sort()
        ret = set()
        for i in range(n):
            ll = self.threeSum(nums, target-nums[i], i+1, n-1)
            if ll == list():
                continue
            for l in ll:
                ret.add(tuple(l))
        return list(ret)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值