力扣 15 三数之和 中等


题目链接

https://leetcode-cn.com/problems/3sum/

1、题目要求

https://leetcode-cn.com/problems/3sum/

简而言之,找到一个数组中相加为 0 的三个元素;
找出所有的组合,且不能重复;

2、思路分析 基于双指针法解决(L R)

此处的三元组暂且定义为:数组找到三个相加为 0 的元素,这三个元素一起组成的叫做三元组;

在数组找到三个相加为 0 并且不重复的三元组,就是找到数组中满足条件的数组下标(3个下标)(i L R)找到的下标都是不重复的;

  • 1、将数组进行排序,方便后面的排查重复元素;
  • 2、以数组中的每一个元素假设可以成为三元组的第一个元素(所以循环是 int i = 0 开始),L = i + 1; R = len - 1;进行循环寻找合适的数组下标;
  • 3、第一个元素 i 的确定: 满足第一个元素不能大于 0 (因为从小到大排序后的数组第一个元素大于 0,该数组 任意三个元素相加不可能等于 0)
    并且满足 i 是不重复的
  • 4、L 的确定:不重复并且满足 sum = 0;
  • 5、R 的确定:不重复并且满足 sum = 0;

3、执行代码 Java

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        // 将数组中的元素找到,寻找三个数字之和为 0 的选项,作为一个三元组进行保存
        // List<> 里面嵌套的是一个 List; 一个 List 每个 List 的单元都可以保存一个 List,实现了三元组的保存
        List<List<Integer>> list = new ArrayList<>(); // size(); ArrayList 里面使用的是 size 查看大小

        int len = nums.length;
        if (nums == null || len < 3) {
            return list;
        }
        Arrays.sort(nums);

        for (int i = 0; i < len; i++) {
            if (nums[i] > 0) {
                break;
            }

            if (i > 0 && nums[i] == nums[i - 1]) {
                // 保证了 i 指向的元素是没有重复的
                continue;
            }

            int L = i + 1;
            int R = len - 1;

            while (L < R) {
                int sum = nums[i] + nums[L] + nums[R];
                if (sum == 0) {
                    list.add(Arrays.asList(nums[i],nums[L],nums[R]));

                    while (L < R && nums[L] == nums[L + 1]) {
                        L++;
                    }

                    while (L < R && nums[R] == nums[R - 1]) {
                        R--;
                    }
                    L++; // 保证了 L 指向的元素是没有重复的
                    R--; // 保证了 R 指向的元素是没有重复的
                } else if(sum < 0){
                    L++; // 求和小于 0 ,负数的绝对值太大了,让负数的绝对值小一点;因为排好了顺序,向着右边移动会减小(在负数到 0 的区间移动)
                } else if(sum > 0) {
                    R--; // 求和大于 0 ,正数的绝对值太大了,让正数的绝对值小一点;因为排好了顺序,向着左边移动会减小(在正数到 0 的区间移动)
                }
            }
        }
        return list;
    }
}

4、问题反思

4.1、关于判断条件的理解

if(i > 0 && nums[i] == nums[i - 1]) ;
确定 i 的时候需要和前面已经出现过的 i 进行比较;

while(L < R && nums[L] == nums[L + 1])
确定 L 的时候需要和后面已经出现过的 L 进行比较;

while(L < R && nums[R] == nums[R - 1])
确定 R 的时候需要和前面已经出现过的 R 进行比较;

5、小结

将题目转换成为寻找数组中满足三个元素相加为 0 的数组下标;在实现过程中,注意避免重复的实现细节; 中等题目;

posted @   YIMENG-0  阅读(22)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示