Leetcode找三个数字的和满足xx条件的题目总结15➕16➕259

双指针最基础的题目是一个区间里找两个数字的和等于Target。首先将区间从小到大排序。接下来只要一个le指针,一个ri指针,分别从区间左右边界往中间推进即可。复杂度是排序的nlogn。

下面几道题都是一个区间里找三个数字的和满足xx条件的。这个题目的做法首先还是先排序。之后先固定一个数字,然后在该数字的右侧区间内重新使用之前找两个数字的和的算法。i 从0到n-1,j 从i+1开始增加,k 从n-1开始减小直到j和k碰撞。这样的复杂度是n平方。外层i从0到n-1是O(n),内层从i+1到n-1也是O(n)。

15

在这里插入图片描述

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        if(nums.empty()){return vector<vector<int>>();}
		sort(nums.begin(),nums.end());
		vector<vector<int>> res;
		int n=nums.size();
		for(int i=0;i<n;++i){
			if(i>0 and nums[i-1]==nums[i]){continue;}
			int j=i+1,k=n-1;
			while(j<k){
				while(j<k and j>i+1 and nums[j]==nums[j-1]){
					++j;
				}
				while(j<k and k<n-1 and nums[k]==nums[k+1]){
					--k;
				}
				if(j>=k){break;}
				if(nums[i]+nums[j]+nums[k]>0){
					--k;
				}
				else if(nums[i]+nums[j]+nums[k]<0){
					++j;
				}
				else{
					res.push_back({nums[i],nums[j],nums[k]});
					++j,--k;
				}
			}
		}
		return res;
    }
};

16

在这里插入图片描述

class Solution {
public:
    int threeSumClosest(vector<int>& nums, int target) {
        int n=nums.size();
        if(n<3){return 0;}
        sort(nums.begin(),nums.end());
        int min_distance=INT_MAX,temp,sum=0;
        for(int i=0;i<n;++i){
            if(i>0 and nums[i]==nums[i-1]){continue;}
            int j=i+1,k=n-1;
            while(j<k){
                if((temp=nums[i]+nums[j]+nums[k]-target)>0){
                    if(temp<min_distance){
                        min_distance=temp;
                        sum=temp+target;
                    }
                    --k;
                    while(j<k and nums[k]==nums[k+1]){
                        --k;
                    }
                }
                else if(temp<0){
                    if(-temp<min_distance){
                        min_distance=-temp;
                        sum=temp+target;
                    }
                    ++j;
                    while(j<k and nums[j-1]==nums[j]){
                        ++j;
                    }
                }
                else{
                    return target;
                }
            }
        }
        return sum;
    }
};

259

在这里插入图片描述

class Solution {
public:
    int threeSumSmaller(vector<int>& nums, int target) {
        int N=nums.size(),res=0;
        sort(nums.begin(),nums.end());
        for(int i=0;i<N-2;++i){
            int j=i+1,k=N-1;
            while(j<k){
                if(nums[i]+nums[j]+nums[k]<target){
                    res+=k-j;
                    j++;
                }
                else{
                    k--;
                }
            }
        }
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值