【leetcode慢速刷题记录】15. 三数之和

本文介绍了如何运用排序和双指针算法解决LeetCode上的经典面试题——找到数组中和为0的三个整数。文章详细解析了C++和C语言的实现代码,包括特殊情况处理、避免重复值的策略以及循环中的边界条件判断。此外,还提到了C语言解法中*returnSize和*returnColumnsize参数的含义。
摘要由CSDN通过智能技术生成


前言

因为是非常经典的面试题,所以记录一下
(另一道也非常经典的面试题:两数之和


一、题目

在这里插入图片描述


二、方法

排序+双指针

排序是关键的一步,因为这样所有取出来的三元组都能够满足
ak<ai<aj(其中,k<i<j)
排序是为了方便去除重复的情况。

算法思路:

  1. 首先进行特判。根据题目给出的例子,nums长度小于3的情况,直接返回空数组[ ];
  2. 对数组进行排序;
  3. 对排好序的数组进行遍历:
    (1)若nums[i]>0:因为数组已经排好序了,如果nums[i]>0,那么后面的元素肯定也大于零,那么肯定不会有和为0的三元组,所以直接返回结果res;
    (2)判断当前元素是否存在重复值,如果重复的话就跳过,防止重复情况的发生;
    (3)指定双指针
    左指针:l=i+1; 右指针:r=nums.size()-1;
    当l<r时,执行循环:
    <1>如果nums[i]+nums[l]+nums[r]>0,说明nums[r]太大了,所以应该让右指针往左移到下一个,但是应该判断一下此时是否符合l<r,并且r现在指向的元素和将要左移指向的元素是否相同,相同则跳过,继续左移并判断;
    <2>如果nums[i]+nums[l]+nums[r]<0,说明nums[l]太小了,所以应该让左指针往右移到下一个,但是应该判断一下此时是否符合l<r,并且l现在指向的元素和将要右移指向的元素是否相同,相同则跳过,继续右移并判断;
    <3>如果nums[i]+nums[l]+nums[r]=0,则将这个三元组放进res,然后将l指针往右移,并且判断l<r是否符合,l指向的元素是否重复,重复则跳过,r指针往左移,判断l<r是否符合,r指向的元素是否重复,重复则跳过。如果不重复,则指针后移或前移,然后重新判断nums[i]+nums[l]+nums[r]的值。

C++语言代码如下:

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
         vector<vector<int>> res;
         //排序
         sort(nums.begin(), nums.end());
         //如果nums是空数组或者长度小于3,则返回[]也就是空数组
         if(nums.size()<3)return res;

         for(int i=0; i<nums.size(); i++){
             //如果nums[i]大于0,那么之后的数字都是大于0的,肯定不会符合题意了
             if(nums[i]>0)break;
             //去重复
             if(i>0 && nums[i]==nums[i-1])continue;

             int l = i+1;
             int r = nums.size()-1;

             while(l<r){
                 int sum = nums[i]+nums[l]+nums[r];
                 if(sum>0){
                     while(l<r && nums[r]==nums[r-1])r--;
                     r--;
                     continue;
                 }
                 if(sum<0){
                     while(l<r && nums[l]==nums[l+1])l++;
                     l++;
                     continue;
                 }
                 if(sum==0){
                     res.push_back({nums[i],nums[l],nums[r]});

                     while(l<r && nums[r]==nums[r-1])r--;
                     while(l<r && nums[l]==nums[l+1])l++;
                     r--;
                     l++;

                 }

             }
         }

         return res;
    }
};

C语言代码如下:

在这里插入代码片

举个栗子:
step1:
在这里插入图片描述
step2:
在这里插入图片描述
step3:
在这里插入图片描述
step4:
在这里插入图片描述
step5:
在这里插入图片描述
step6:
在这里插入图片描述
step7:
在这里插入图片描述
step8:
在这里插入图片描述
step9:
在这里插入图片描述
step10:
在这里插入图片描述
step11:
在这里插入图片描述
step12:
在这里插入图片描述


一些总结

关于*returnSize 和 *returnColumnsize的解释

C语言解法中传入的参数涉及*returnSize 和 *returnColumnsize,之前没有接触过,所以记录一下需要注意的地方。

C语言默认模板为:
在这里插入图片描述具体可详细参考:

  1. 关于leetcode上*returnSize 与 *returnColumnSizes的实际意义及使用
  2. 详解力扣中int *return Size和int **returnColumnSizes

(这个跟刷题有点关系但是其实跟算法思想关系不大,但是不了解的话又容易不通过)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值