【力扣】15. 三数之和

15. 三数之和 - 力扣(LeetCode)

本题最难的是对于各种情况的判断,还有遍历和判断后的处理是否越界,基本思路很好理解。

引用一下题解中大佬的思路,很清晰易懂(@吴彦祖

  • 特判,对于数组长度 n,如果数组为 null 或者数组长度小于 3,返回 [ ]。
  • 对数组进行排序。
  • 遍历排序后数组:
    • 若 nums[ i ] > 0:因为已经排序好,所以后面不可能有三个数加和等于 0,直接返回结果。
    • 对于重复元素:跳过,避免出现重复解
    • 令左指针 L = i + 1,右指针 R = n − 1,当 L < R 时,执行循环:
    • 当 nums[ i ] + nums[ L] + nums[ R] == 0,执行循环,判断左界和右界是否和下一位置重复,去除重复解。并同时将 L, R 移到下一位置,寻找新的解
    • 若和大于 0,说明 nums[ R] 太大,R 左移
    • 若和小于 0,说明 nums[ L] 太小,L 右移
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> ans;
        int n = nums.size();
        //如果数组大小小于三,或最小值大于零,或最大值小于零,都不可能达到三个数的和为零,直接返回
        sort(nums.begin(), nums.end());//排序
        if(n < 3 || nums.front() > 0 || nums.back() < 0) return ans;
        for(int i = 0; i < n-2; i++){//-2去除左右指针
            //左右指针始终大于nums[i],如果nums[i]大于零说明已经没有三数之和相加为零的情况了
            if(nums[i] > 0) break;
            //判断重复的解
            if(i > 0 && nums[i] == nums[i-1]) continue;
            //判断:三个最小的值相加大于零,说明不可能出现三数之和等于零的情况了,提前终止
            if(nums[i] + nums[i+1] + nums[i+2] > 0) break;
            //判断:nums[i]和最大的两个值相加小于零,说明当前的nums[i]的值太小了,需要继续向前遍历;
            if(nums[i] + nums[n-1] + nums[n-2] < 0) continue;
            //双指针:L为最靠近nums[i]的数,R为最大值。循环条件L<R
            int L = i+1, R = n-1;
            while(L < R){
                int sum = nums[i] + nums[L] + nums[R];//开始计数
                if(sum == 0){
                    //等于零符合条件,压入返回答案的数组中;
                    ans.push_back({nums[i], nums[L], nums[R]});
                    //移动左右指针,判断并排除重复的解;
                    while(L < R && nums[L] == nums[L+1]) L++;
                    L++;//需要移动到L+1的位置
                    while(L < R && nums[R] == nums[R-1]) R--;
                    R--;//同上
                }
                else if(sum < 0) L++;//和小于零移动左指针
                else R--;//和大于零移动右指针
            }
        }
        return ans;
    }
};

(本来想练练排序的结果一个sort()就完事了hh) 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值