2089 字
约 6 分钟
21
LeetCode刷题Java版015.三数之和
无标签

LeetCode刷题Java版015.三数之和

作者:沉默王二
发布时间:2022-07-30T16:58:06.590+0800


015.三数之和

题意

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 ?请你找出所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

难度

中等

示例

输入:nums = [-1,0,1,2,-1,-4]

输出:[[-1,-1,2],[-1,0,1]]

分析

我们之前做过 001.两数之和 这道题,两道题非常相似,虽然各有各的特点,我们却可以从中得到启发,只要将 a + b + c = 0 转移成 a + b = -c 似乎就能套用之前的解题方法,但很遗憾,我们没办法做到,因为目标的值(也就是 -c)一直在改变,两数之和的时候是固定的,所以我们另寻出路。

首先,我们知道这种从 …… 中选 …… 出来的题目,顺序对答案没有影响,所以我们不妨先将整个数组进行排序。

排序后,我们就能得到一个从小到大排列好的数组,这时候我们只需要定一移二就能找出答案了,也就是将a + b + c = 0中的a确定了,再移动后面两个数来获得相应的组合。

但是这样子的时间复杂度是,太大了,不现实。

怎么办呢?

先前做的排序就派上用场了。这时候a确定了,那么我们只要确定b、c即可,首先让lef = i + 1,rig = n - 1(a = nums[i]、b = nums[lef]、c = nums[rig])如果a + b + c < 0,那么如果rig下标向左移动,就会让a + b + c变得更小,肯定不行,于是我们移动lef,让b变大,从而让a + b + c靠近0。a + b + c > 0也是同理,移动rig,让a + b + c减小,从而靠近0。

public class Solution {

 public List<List> threeSum(int[] nums) {

  List<List> res = new ArrayList<>();

  Arrays.sort (nums);

  for(int i = 0;i < nums.length ;i++){

   if( i > 0 && nums[i] == nums[i - 1])

    continue;

   if(nums[i] > 0)

    break;

   int lef = i + 1;

   int rig = nums.length  - 1;

   while(lef < rig){

    if(nums[i] + nums[lef] + nums[rig] < 0)

     lef++;

    else{

     if(nums[i] + nums[lef] + nums[rig] == 0){

      res.add (Arrays.asList(nums[i],nums[lef],nums[rig]));

      while(lef < rig && nums[lef] == nums[lef + 1]) lef++;

      while(lef < rig && nums[rig] == nums[rig - 1]) rig--;

      lef++;

     }

     rig--;

    }

   }

  }

  return res;

 }

}

注意题解中的一个细节,就是我们需要去重,防止重复的三元组出现,每次选择一个lef或者rig,都需要移动到下一个不同的位置处。

总结

本次我们采用定一移二的方法,将整个数组排序后,利用其有序性,巧妙地排除了很多不可能的答案,从而将时间复杂度从降为。我们在面对这一系列(从一些元素中选出几个)的时候,他们之间的顺序关系往往是不影响结果的,那么我们就可以将其排序,再仔细观察,有时解题的关键就藏于其中。

力扣链接:https://leetcode.cn/problems/3sum/

015.三数之和

题意

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 ?请你找出所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

难度

中等

示例

输入:nums = [-1,0,1,2,-1,-4]

输出:[[-1,-1,2],[-1,0,1]]

分析

我们之前做过 001.两数之和 这道题,两道题非常相似,虽然各有各的特点,我们却可以从中得到启发,只要将 a + b + c = 0 转移成 a + b = -c 似乎就能套用之前的解题方法,但很遗憾,我们没办法做到,因为目标的值(也就是 -c)一直在改变,两数之和的时候是固定的,所以我们另寻出路。

首先,我们知道这种从 …… 中选 …… 出来的题目,顺序对答案没有影响,所以我们不妨先将整个数组进行排序。

排序后,我们就能得到一个从小到大排列好的数组,这时候我们只需要定一移二就能找出答案了,也就是将a + b + c = 0中的a确定了,再移动后面两个数来获得相应的组合。

但是这样子的时间复杂度是,太大了,不现实。

怎么办呢?

先前做的排序就派上用场了。这时候a确定了,那么我们只要确定b、c即可,首先让lef = i + 1,rig = n - 1(a = nums[i]、b = nums[lef]、c = nums[rig])如果a + b + c < 0,那么如果rig下标向左移动,就会让a + b + c变得更小,肯定不行,于是我们移动lef,让b变大,从而让a + b + c靠近0。a + b + c > 0也是同理,移动rig,让a + b + c减小,从而靠近0。

public class Solution {

 public List<List> threeSum(int[] nums) {

  List<List> res = new ArrayList<>();

  Arrays.sort (nums);

  for(int i = 0;i < nums.length ;i++){

   if( i > 0 && nums[i] == nums[i - 1])

    continue;

   if(nums[i] > 0)

    break;

   int lef = i + 1;

   int rig = nums.length  - 1;

   while(lef < rig){

    if(nums[i] + nums[lef] + nums[rig] < 0)

     lef++;

    else{

     if(nums[i] + nums[lef] + nums[rig] == 0){

      res.add (Arrays.asList(nums[i],nums[lef],nums[rig]));

      while(lef < rig && nums[lef] == nums[lef + 1]) lef++;

      while(lef < rig && nums[rig] == nums[rig - 1]) rig--;

      lef++;

     }

     rig--;

    }

   }

  }

  return res;

 }

}

注意题解中的一个细节,就是我们需要去重,防止重复的三元组出现,每次选择一个lef或者rig,都需要移动到下一个不同的位置处。

总结

本次我们采用定一移二的方法,将整个数组排序后,利用其有序性,巧妙地排除了很多不可能的答案,从而将时间复杂度从降为。我们在面对这一系列(从一些元素中选出几个)的时候,他们之间的顺序关系往往是不影响结果的,那么我们就可以将其排序,再仔细观察,有时解题的关键就藏于其中。

力扣链接:https://leetcode.cn/problems/3sum/

015.三数之和

题意

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 ?请你找出所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

难度

中等

示例

输入:nums = [-1,0,1,2,-1,-4]

输出:[[-1,-1,2],[-1,0,1]]

分析

我们之前做过 001.两数之和 这道题,两道题非常相似,虽然各有各的特点,我们却可以从中得到启发,只要将 a + b + c = 0 转移成 a + b = -c 似乎就能套用之前的解题方法,但很遗憾,我们没办法做到,因为目标的值(也就是 -c)一直在改变,两数之和的时候是固定的,所以我们另寻出路。

首先,我们知道这种从 …… 中选 …… 出来的题目,顺序对答案没有影响,所以我们不妨先将整个数组进行排序。

排序后,我们就能得到一个从小到大排列好的数组,这时候我们只需要定一移二就能找出答案了,也就是将a + b + c = 0中的a确定了,再移动后面两个数来获得相应的组合。

但是这样子的时间复杂度是,太大了,不现实。

怎么办呢?

先前做的排序就派上用场了。这时候a确定了,那么我们只要确定b、c即可,首先让lef = i + 1,rig = n - 1(a = nums[i]、b = nums[lef]、c = nums[rig])如果a + b + c < 0,那么如果rig下标向左移动,就会让a + b + c变得更小,肯定不行,于是我们移动lef,让b变大,从而让a + b + c靠近0。a + b + c > 0也是同理,移动rig,让a + b + c减小,从而靠近0。

public class Solution {

 public List<List> threeSum(int[] nums) {

  List<List> res = new ArrayList<>();

  Arrays.sort (nums);

  for(int i = 0;i < nums.length ;i++){

   if( i > 0 && nums[i] == nums[i - 1])

    continue;

   if(nums[i] > 0)

    break;

   int lef = i + 1;

   int rig = nums.length  - 1;

   while(lef < rig){

    if(nums[i] + nums[lef] + nums[rig] < 0)

     lef++;

    else{

     if(nums[i] + nums[lef] + nums[rig] == 0){

      res.add (Arrays.asList(nums[i],nums[lef],nums[rig]));

      while(lef < rig && nums[lef] == nums[lef + 1]) lef++;

      while(lef < rig && nums[rig] == nums[rig - 1]) rig--;

      lef++;

     }

     rig--;

    }

   }

  }

  return res;

 }

}

注意题解中的一个细节,就是我们需要去重,防止重复的三元组出现,每次选择一个lef或者rig,都需要移动到下一个不同的位置处。

总结

本次我们采用定一移二的方法,将整个数组排序后,利用其有序性,巧妙地排除了很多不可能的答案,从而将时间复杂度从降为。我们在面对这一系列(从一些元素中选出几个)的时候,他们之间的顺序关系往往是不影响结果的,那么我们就可以将其排序,再仔细观察,有时解题的关键就藏于其中。

力扣链接:https://leetcode.cn/problems/3sum/

            知识星球
            
    
    
        
        扫码加入星球
        查看更多优质内容
    
    https://wx.zsxq.com/mweb/views/joingroup/join_group.html?group_id=15522885221412
LeetCode刷题Java版015.三数之和
https://clxhxhhr.top/posts/2569/
作者
clxstart
发布于
2026-09-19
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。