当前位置: 首页 > news >正文

三数之和_算法

1.题目描述

首先我们分析下这道题目:假设给我们一个数组,让数组某三个不同下标的数相加最终得0,那么我就返回这三个数.但是如果返回的多个数组中的元素相同,那么我们还要删掉其中一个保留一个.

注意:这道题的重点是三个数的下标不能相等并且返回的数组中的元素也不能相等,通过示例1我们就能看出由于有两个[0,-1,1],我们返回其中一个就可以了

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

2.算法分析

上面我们已经对题目进行了分析,首先我们对数组进行一个排序.那么我们的思路就是先固定一个数"i",利用双指针算法找到两个数相加等于 "-i"(定义为target),那么我们就将下标为i,left,right代表的值返回.

这里有一个很重要的思路就是当我们排序之后,如果nums[left]+nums[right]<target,就证明nums[left]太小了,我们就要让left++,让他nums[left]的值变大,看看是否加上nums[right]==target,如果nums[left]+nums[right]>arget,就证明nums[right]太大了,让right--;这是我们这个双指针解决这道题算法的一个核心思路.

---------------------------------------------------------------------------------------------------------------------------------

小细节:

1.那么我们如何达到去重呢?

其实很简单,如果下标left的值等于left-1的值,那么我们就让left++,right的值等于right+1的值,right--.

这里我们要做两层去重,

第一层去重:我们要先判断left下标的值和left-1的值是否相等,相等left++,判断right和right+1的值是否相等,相等right--.

第二层去重:我们固定的数  i  也可能会重复,那么"-i"(target),也会导致和上一次相同.可能导致两次遍历的结果一样.所以我们对 i 也要进行去重

 2.越界问题

当然,如果数组全是0,那么可能会造成越界问题.

---------------------------------------------------------------------------------------------------------------------------------

执行完一次循环就让我们的i++,如果i也相同,就跳过,继续往后边走.

小优化: 

当 i 大于0的时候我们就可以结束循环,因为我们已经对数组进行了排序,如果i大于0,那么left下标的值+right的值会比 i 还大,而且永远不会相等.因为只有i等于负数的时候三个数相加才有可能等于0

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

3.代码实现

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        //创建一个集合用于返回三个数组成的数组
        List<List<Integer>> ret=new ArrayList<>();
        //对数组nums进行排序
        Arrays.sort(nums);
      
        int n=nums.length;
        //for循环固定 i 
        for(int i=0;i<n;){
            //如果i大于0直接返回
            if(nums[i]>0) break;
            //left和right要在i后面的区间进行扫描
            int left=i+1;
            int right=n-1;
            int target=-nums[i];
            while(left<right){
                if(nums[left]+nums[right]<target) {
                     left++;
                }else if(nums[left]+nums[right]>target){
                    right--;
                } else{
                    //返回这三个数
                     ret.add(new ArrayList<Integer>(Arrays.asList(nums[i],nums[left],nums[right])));
                     //可能还会有,还要继续扫描
                     left++;
                     right--;
                     //去重(注意越界)
                    while(left<right&&nums[left]==nums[left-1]) left++;
                    while(left<right&&nums[right]==nums[right+1]) right--;
                }
     
            }
            //i也要去重,并且也要防止越界
            i++;
            while(i<n&&nums[i]==nums[i-1]) i++;
        }
        return ret;

    }
   
}

 

相关文章:

  • 期权学习与期权异动
  • iOS 使用消息转发机制实现多代理功能
  • 如何将Vue项目部署至 nginx
  • Trae智能协作AI编程工具IDE:如何在MacBook Pro下载、安装和配置使用Trae?
  • DeepSeek 与大数据治理:AI 赋能数据管理的未来
  • W3C标准和ES规范之一文通
  • FPGA开发,使用Deepseek V3还是R1(3):系统级与RTL级
  • SpringBoot 端口配置
  • nlp第七节——文本匹配任务
  • 下载 MindSpore 配置 PyTorch环境
  • 使用消息队列怎样防止消息重复?
  • 苹果廉价机型 iPhone 16e 影像系统深度解析
  • Rust ~ Dyn Error
  • C语言:质因数分解
  • SpringCloud基础学习
  • C++11特性(笔记二lambda,function)
  • 《解锁万相2.1大模型:开启视频创作新世界》:此文为AI自动生成
  • 聊一聊 IM 如何优化监控
  • spring boot打包插件的问题
  • 计算机毕业设计SpringBoot+Vue.js医院资源管理系统(源码+文档+PPT+讲解)
  • 朝鲜称将在各领域采取反制措施,应对美国敌对挑衅
  • 俄媒:俄乌代表团抵达谈判会场
  • 中国首艘海洋级智能科考船“同济”号试航成功,可搭载水下遥控机器人
  • 特朗普称即将与伊朗达成核协议,外交部:中方愿继续发挥建设性作用
  • 人形机器人灵犀X2掌握新技能:有了“内心戏”,还会拳脚功夫
  • 新华时评:让医德医风建设为健康中国护航