LeetCode每日1题--三数之和

简介: LeetCode每日1题--三数之和

前言


算法的重要性不言而喻!区分度高!

现在学习的门槛低了,只有能上网每个人都可以学编程!培训班6个月就可以培养出来能干活的人,你怎么从这些人中脱颖而出?没错!就是学算法,学一些底层和基础的东西。

说的功利点是为了竞争,卷死对手。真心话说就是能提高自己的基础能力,为技术可持续发展做好充分的准备!!!

提前入门学习书籍:CPrimerPlus、大话数据结构

image.png


刷题网站


代码随想录 (programmercarl.com)

leetcode

我是按照代码随想录提供的刷题顺序进行刷题的,大家也可以去刷leetcode最热200道,都可以

刷题嘛,最重要的就是坚持了!!!


画图软件


OneNote

这个要经常用,遇见不懂的流程的话就拿它画一画!


笔记软件


Typoral


题目


image.png


解析


暴力思路

三层for循环 都可以想到的方法,但是它行不行呢?

public class TheSumOfThreeNumbers {
    public static void main(String[] args) {
        int[] nums = {-1, 0, 1, 2, -1, -4};
        ArrayList<List<Integer>> arrayList = new ArrayList<>();
        for (int i = 0; i < nums.length; i++) {
            for (int j = i + 1; j < nums.length; j++) {
                for (int k = j + 1; k < nums.length; k++) {
                    int sum = nums[i] + nums[j] + nums[k];
                    if (sum == 0){
                        arrayList.add(Arrays.asList(nums[i],nums[j],nums[k]));
                    }
                }
            }
        }
        arrayList.forEach(x -> System.out.println(x));
    }
}

image.png

不太行,因为[-1,0,1],[0,1,-1]]算是重复的啦,换位置也不行

双指针

这题的确不好想,看题解中的例子是使用指针的方法:

  1. 首先对数组排序
  2. 定义二个指针
  3. 循环for目的是遍历数组,i从下标0开始
  4. 第一个指针left从i+1开始,代表第二个数
  5. 第二个指针right在数组尾部,代表第三个数

相当于 a = nums[i],b = nums[left],c = nums[right]。

接下来如何移动left 和right呢?

想起我们刚开始对数组做的排序了吗?如果nums[i] + nums[left] + nums[right] > 0 就说明 此时三数之和大了所以right下标就应该向左移动,这样才能让三数之和小一些。

nums[i] + nums[left] + nums[right] < 0 说明三数之和小了,left就向右移动,才能让三数之和大一些,直到left与right相遇为止。

时间复杂度:O(n^2)。


public static List<List<Integer>> threeSum(int[] nums) {
        ArrayList<List<Integer>> result = new ArrayList<>();//存放结果集,格式为[[],[],[]....]
        Arrays.sort(nums); //对目标数据进行排序
        if (nums == null || nums.length < 3) {
            return result;
        }
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] > 0) {
                return result;      //临界条件的一些判断,如果排序后的第一个数都大于0那么三数之后不可能为0
            }
            /**
             * 加上i > 0是因为第一个数没和前一个数比较,会出现数组越界
             * 为i-1是因为,i是增加的,它要和后面的数比较看是否相等
             */
            if (i > 0 && nums[i] == nums[i - 1]) { //
                continue;   //这里是对i的去重
            }
            int left = i + 1;   //左指针
            int right = nums.length - 1;    //右指针
            while (right > left) {
                int sum = nums[i] + nums[left] + nums[right];
                if (sum > 0) {
                    right--;    //和大于0,说明加的太大了,只能让right左移
                } else if (sum < 0) {
                    left++; //和小于0,说明加的太小了,只能让left右移
                } else {
                    result.add(Arrays.asList(nums[i], nums[left], nums[right]));//等于0,加入结果集
                    while (right > left && nums[left] == nums[left + 1]) left++;//对右指针去重
                    while (right > left && nums[right] == nums[right - 1]) right--;//对左指针去重
                    right--;//往左移动
                    left++;//往右移动
                }
            }
        }
        return result;
    }

代码中也有详细的解释,实在不明白的话可以dubug一下image.png



相关文章
|
3月前
|
Java C++ Python
leetcode-15:三数之和
leetcode-15:三数之和
20 0
|
4月前
|
算法 C++
(C++)三数之和--双指针法
(C++)三数之和--双指针法
20 0
|
4月前
|
算法 C++
(C++)四数之和--双指针法
(C++)四数之和--双指针法
26 0
|
10月前
|
存储
力扣 -- 15.三数之和
力扣 -- 15.三数之和
|
10月前
|
算法 测试技术
leetcode:15.三数之和
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
58 0
|
11月前
|
算法
LeetCode每日1题--四数之和
LeetCode每日1题--四数之和
57 0
|
11月前
|
算法
LeetCode每日1题--螺旋矩阵
LeetCode每日1题--螺旋矩阵
48 0
LeetCode每日1题--螺旋矩阵
|
11月前
|
存储 算法 索引
LeetCode每日1题--两数之和
LeetCode每日1题--两数之和
71 0
|
11月前
|
算法
LeetCode每日1题--左旋转字符串
LeetCode每日1题--左旋转字符串
72 0
|
Java C++ Python
【LeetCode】 15. 三数之和
第15题. 三数之和
56 0
【LeetCode】 15.  三数之和