java数据结构与算法刷题-----LeetCode15. 三数之和

遗传病变异注释预测工具安装系列之------Exomiser 安装及bug处理 Exomiser是一个Java程序,它从全外显子组或全基因组测序数据中发现潜在的致病变异。 Java 版本必须为1.8以上。 Exomiser 最新版本下载 wget -c https://github.com/exomiser/Exomiser/releases/download/11.0.0/exomiser-cli-11.0.0-distribution.zip unzip ... 阅读详情
java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.youkuaiyun.com/grd_java/article/details/123063846

在这里插入图片描述

解题思路
  1. 和LeetCode1.两数之和一样,但是这道题边界条件更多。
  2. 两数之和那道题目中,我们使用了map进行处理,也讲了如果投机取巧,用大量的数组空间充当map集合,从而达成相同的逻辑处理代码,只是将map换成数组,却比map集合快很多的办法。
  3. 这道题也同样可以用map集合,但是因为边界条件过多,代码十分繁琐,尤其是投机取巧用数组充当hash,确实在做题方面,可以达成超越100%的用户,但是没有任何实际意义,只能做题。(后面也会将代码给出)
  4. 所以这道题,我会给出比较靠谱的办法,时间复杂度也不高,工作中推荐使用。那就是排序+双指针
  5. 先对整个数组排序,然后创建3个指针,从第一个数开始向后枚举
  6. 第一个指针 i 只是起到限定第一个数的作用,我们需要通过双指针left和right,来找到第一个数的右边区域的另外两个数
  7. 初始left左指针指向第一个数 i 的右边第一个位置,而right指向右边区域末尾,如果3个数相加比0大,就说明right指向的数太大,right–即可,反之,如果相加比0小,left就太小了,进行left++。
代码,时间复杂度O(n^2),空间复杂度,数组需要排序,工作场景中,不可以改变原数组,因此需要O(n)空间复杂度来排序。然后排序算法使用快速排序,需要O(logN)的栈空间复杂度。
  1. 方法一:排序+双指针,效率肯定比不过方法二的hash表,而且使用数组当hash表,但是实际工作中,肯定使用方法一。此方法耗时25ms, 方法二耗时0ms
    在这里插入图片描述
class Solution {

    public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);//先排序,为了双指针枚举提供方便
        List<List<Integer>> ans = new ArrayList<>();//答案需要的链表
        int n = nums.length;//n代表数组长度
        for (int i = 0; i < n - 2; ++i) {//因为需要3个数,所以第一个数最多到---倒数第3个
            int x = nums[i];//x保存当前遍历的第一个数
            if (i > 0 && x == nums[i - 1]) continue; // 跳过重复数字,枚举过的,就不重复枚举了
            // 优化一:因为数组排序后是从小到大,如果当前第一个数+它后面两个数,就已经>0了,那当前枚举,包括后面的,都不会符合条件
            if (x + nums[i + 1] + nums[i + 2] > 0) break; 
            // 优化二:如果当前数+倒数那两个数(从小到大排序,也就是末尾的都是最大的)都小于0的话,那也就不用在考虑这个枚举了。肯定枚举不出来
            if (x + nums[n - 2] + nums[n - 1] < 0) continue; 
            //左右指针
            int left = i + 1, right = n - 1;
            while (left < right) {//只要还有元素可以枚举就继续
                int s = x + nums[left] + nums[right];//3个数的和
                if (s > 0) --right;//如果s比0大,说明right指向的太大的,right--
                else if (s < 0) ++left;//如果s比0小,说明left指向太小,left++
                else {//如果s = 0,说明找到了,添加到链表,然后将继续进行下次枚举
                    ans.add(List.of(x, nums[left], nums[right]));//添加到链表
                    //进行下次枚举之前,我们可以跳过已经枚举过的,也就是和当前left和right数字重复的
                    //因为答案中不要重复的元素
                    for (++left; left < right && nums[left] == nums[left - 1]; ++left); // 跳过重复数字
                    for (--right; right > left && nums[right] == nums[right + 1]; --right); // 跳过重复数字
                }
            }
        }
        return ans;//返回答案
    }
}
  1. 方法二:使用hash表,用数组充当hash,空间复杂度不确定,取决于数组中存储的值的范围,如果一共有两个元素,[1,999999],那么空间复杂度就是999999. 所以,这是投机取巧的方法,但是做题的效率确实快。只用了0ms
    在这里插入图片描述
//C(n, k) = C(n - 1, k) + C(n - 1, k - 1)
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        return nSum(nums, 3, 0);
    }

    public List<List<Integer>> fourSum(int[] nums, int target) {
        return nSum(nums, 4, target);
    }

    public List<List<Integer>> nSum(int[] nums, int k, int target) {
        return new AbstractList<List<Integer>>() {
            final List<List<Integer>> res = new ArrayList<>();
            final List<Integer> path = new ArrayList<>();
            long min;

            @Override
            public List<Integer> get(int index) {
                init();
                return res.get(index);
            }

            @Override
            public int size() {
                init();
                return res.size();
            }

            public void init() {
                if (res.isEmpty()) {
                    int n = nums.length;
                    long[] Arr = new long[n];
                    Arrays.sort(nums);
                    min = nums[0];
                    for (int i = 0; i < n; i++) {
                        Arr[i] = nums[i] - min;
                    }
                    long NewTarget = (long)target - (long)k * min;
                    C(false, Arr, n, k, NewTarget);
                }
            }

            //C(n, k) = C(n - 1, k) + C(n - 1, k - 1)
            public void C(boolean T, long[] a, int n, int k, long target) {
                if (n == 0 || k == 0) {
                    if (target == 0 && k == 0) {
                        res.add(new ArrayList<>(path));
                    }
                    return;
                }
                if (k == 2) {
                    if (!T && n != a.length && a[n] == a[n - 1]) {
                        return;
                    }
                    //两数之和模板
                    twoSum(a, 0, n - 1, target);
                    return;
                }
                if (n == k) {
                    if (!T && n != a.length && a[n] == a[n - 1]) {
                        return;
                    }
                    //数组中元素和是否等于target
                    sumArr(a, n, target);
                    return;
                }
                if (check(a, n, k, target)) {
                    return;
                }
                C(false, a, n - 1, k, target);
                if (!T && n != a.length && a[n] == a[n - 1]) {
                    return;
                }
                if (target - a[n - 1] >= 0) {
                    path.add((int) (a[n - 1] + min));
                    C(true, a, n - 1, k - 1, target - a[n - 1]);
                    path.remove(path.size() - 1);
                }
            }

            void twoSum(long[] a, int l, int r, long target) {
                if (l >= r || a[r - 1] + a[r] < target || a[l] + a[l + 1] > target) {
                    return;
                }
                while (r > l) {
                    long sum = a[l] + a[r];
                    if (sum < target) {
                        l++;
                    } else if (sum > target) {
                        r--;
                    } else {
                        path.add((int) (a[l] + min));
                        path.add((int) (a[r] + min));
                        res.add(new ArrayList<>(path));
                        path.remove(path.size() - 1);
                        path.remove(path.size() - 1);
                        while (r > l && a[l] == a[l + 1]) {
                            l++;
                        }
                        while (r > l && a[r] == a[r - 1]) {
                            r--;
                        }
                        l++;
                        r--;
                    }
                }
            }

            void sumArr(long[] a, int n, long target) {
                for (int i = n - 1; i > -1; i--) {
                    target -= a[i];
                    path.add((int) (a[i] + min));
                }
                if (target == 0) {
                    res.add(new ArrayList<>(path));
                }
                for (int i = n - 1; i > -1; i--) {
                    target += a[i];
                    path.remove(path.size() - 1);
                }
            }

            boolean check(long[] a, int n, int k, long target) {
                if (n - k < 0) {
                    return true;
                }
                long max = 0;
                long min = 0;
                for (int i = 0; i < k; i++) {
                    min += a[i];
                    max += a[n - i - 1];
                }
                if (target < min || target > max) {
                    return true;
                }
                return false;
            }
        };
    }
}
AUTOSAR从入门到精通-中间件通信DDS(一) 汽车开放系统架构(automotive open system architecture,autosar)是由全球各大汽车oem、零部件供应商、汽车电子软件公司联合建立的一套标准协议。该协议规范了一个符合汽车电子软件开发的、开放的以及标准化的软件架构。最初的autosar规范的制定只考虑传统汽车电子电器架构,基于硬件算力有限场景,提供确定的功能。 阅读详情

相关推荐

OpenEuler内核编译及替换

一、内核源码下载 在gitee上下载OpenEuler内核源码 下载地址 选择需要的内核版本源码压缩包进行下载 二、内核编译 1.解压缩 将下载好的源码进行解压 tar xvf openeuler-kernel-4.19.90-2107.1.0.tar.gz 2.清理源代码树 解压后得到一个名为kernel的内核源码文件夹,进入后执行命令 make mrproper 清理过去内核编译产生的config,第一次编译时可不执行此命令 3.生成内核配置文件.config 先将将系统原配置文件拷贝过来,原

m0_56602092的博客 2万+

LeetCode做题总结 15. 三数之和、18. 四数之和 (Java)

LeetCode做题总结 15. 三数之和、18. 四数之和 (Java)

yavlgloss的博客 616

记录Nvidia AGX Orin的配置日常(二)设置上电自动开机和远程桌面

因为要拿AGX作为机器人的主控板,所以需要给他设置一下通电后无需按电源键就自动开机,然后再配置一下远程桌面。

AutomaticForever的博客 1364

leetcode 15. 三数之和(Java版的三种解法)

题目描述(题目难度,中等) 给定一个包含n个整数的数组nums,判断nums中是否存在三个元素a,b,c,使得a + b + c= 0 ?找出所有满足条件且不重复的三元组。 注意:答案中不可以包含重复的三元组。 例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4], 满足要求的三元组集合为: [ [-1, 0, 1], [-1, -1, 2] ] 解法一(不排序) 这个题目的难点之一,就是要求输出的三元组不重复。如果想要在不对原始数...

u011250186的博客 1142

[亚信线上教学] AX58100: EtherCAT从站设备仿真功能设计教学

什么情况需要开启EtherCAT从站设备仿真功能呢? 一般来说, 当EtherCAT从站产品,不需要使用额外的微控制器介入,或使用不具备EtherCAT从站通讯协议栈的微控制器一同协作的情况下,就必须开启EtherCAT从站设备仿真功能,这样EtherCAT主站才能够正常设置从站设备的工作状态. 亚信AX58100 EtherCAT从站控制芯片的优点 AX58100 EtherCAT从站控制器, 集成2个百兆以太网Phis, 并支持一些额外的控制接口, 例如脉冲宽度调变, 增量, 霍尔编码器, .

allanchou1的专栏 7425

【UV打印机】PrintExp打印软件教程(二)-主界面介绍

PrintExp软件主界面如下图所示PrintExp软件的主界面主要包括主菜单区,工具栏区,界面显示区,状态栏。以下是上述部分的介绍。

Print World的专栏 6301

LeetCode(力扣)数组篇 JAVA刷题详解

是不是有许多小伙伴在刷力扣的时候感觉无从下手?从头按顺序开始刷的童鞋们可能会比较有感触,为什么才第四题就感觉很难了?没关系,本文将对力扣的 1-500 题中不需要会员的数据结构与算法题目(数据库与 shell 除外)进行分类,并推荐一个刷题的顺序。完全零基础可以刷题吗?不能,至少要基本掌握一门计算机语言的语法。但现在在网上随便搜一下就能搜到许多关于计算机语言的教程。当然,最好还是上一下正规的课程。刷题顺序很重要吗?重要。按照题目类别结构化地刷题的速度不仅更快,而且可以在刷完一类题之后进行总结。

weixin_61779644的博客 2538

编程实践:寒武纪-LLM&VLM模型量化&部署

本文介绍了在MLU370-S4平台上对大模型(LLM/VLM)进行量化的两种方法:SmoothQuant和WeightOnly。以Qwen2-VL-2B模型为例,详细说明了两种量化方式的命令行参数配置,包括必须设置的per_channel选项和量化参数调整建议。量化完成后,提供了模型部署的具体命令示例,包含设备分配、端口设置、并行度等关键参数。文章强调在MLU370芯片上需要手动设置block_size,并指出两种量化方式只能二选一使用。配套资料已上传至百度网盘供参考。

微风❤水墨 510

LeetCode刷题攻略

通过这套方法,一般3-6个月可系统提升算法能力。例如,某学员按此方案从AC率40%提升至周赛稳定3题,最终获得微软Offer。关键在于坚持结构化训练而非碎片化刷题。刷 LeetCode 是提升算法和数据结构能力的高效方式,但需要科学的方法才能事半功倍。

Dontla的博客 4486

Pytorch图像去噪实战(七):Noise2Noise自监督图像去噪实战,没有干净图也能训练模型

PyTorch图像去噪实战:Noise2Noise自监督去噪方法 本文介绍了在没有干净图像的情况下使用Noise2Noise方法进行图像去噪的实战方案。主要内容包括: 问题场景:真实项目中经常只有带噪图像而没有对应的干净图像,如夜间监控、医学影像等场景。 Noise2Noise核心思想:使用同一场景的两张不同噪声版本的图像进行训练(noisy_image_a → noisy_image_b),让模型学习恢复共同的干净结构而非随机噪声。 技术原理:模型通过最小化两个独立噪声图像之间的差异,最终会收敛到真实干净

ai技术增长的博客 502

【100分】【等和子数组最小和】

逆序排序,这样能够使得在分组时优先选取较大的元素,以便将元素分配到较小的子集中,从而使得每个子集的和相对均衡。给定一个数组nums,将元素分为若干个组,使得每组和相等,求出满足条件的所有分组中,组内元素和的最小值。分成若干个组,使得每组的和相等,并求出满足条件的所有分组中,组内元素和的最小值。在递归的过程中,我们需要注意一个优化点,即避免将相同和的桶重复计算。4 个子集(5),(1,4),(2,3),(2,3)2 个子集(5, 1, 4),(2,3, 2,3)个子集,则返回子集和的最小值,如果不能,则将。

weixin_54707168的博客 1169

LeetCode刷题汇总

剑指offer 剑指 Offer 03 数组中重复的数字 剑指 Offer 04 二维数组中的查找 剑指 Offer 05 替换空格 剑指 Offer 06 从尾到头打印链表 剑指 Offer 07 重建二叉树 剑指 Offer 09 用两个栈实现队列 剑指 Offer 10- I 斐波那契数列 剑指 Offer 10- II 青蛙跳台阶问题 剑指 Offer 11 旋转数组的最小数字 剑指 Offer 12 矩阵中的路径 剑指 Offer 13 机器人的运动范围 剑指 Offer 14- I 剪绳子 剑指

weixin_44171872的博客 2万+

AUTOSAR知识点 之 XCP (三):XCP功能描述

记录一下XCP使用时候的功能包含命令时序、错误码表、事件描述以及对规范的记录。XCP的图示如下从上图就可以看出数据流的流向CAN-CANIF-XCP,发送反之。XCP的状态机如下。

梦想技术家 3079

数据结构与算法(Java笔记15天)

文章目录Java数据结构与算法前言目录结束 Java数据结构与算法 前言 源码:https://github.com/name365/Java-Data-structure 目录 名称 地址 第一章 稀疏数组 https://blog.csdn.net/m0_46153949/article/details/106266666 第二章 队列 https://blog.csdn.net/m0_46153949/article/details/106266666 第三章 链表 htt

杨丙寅 1万+

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

力扣刷题路线

结合高频题、经典题和算法思想学习建议,分阶段从基础到进阶编排,覆盖所有核心标签,并标注题号与学习方法。:画图模拟快慢指针移动,如移动零时快指针探路、慢指针标记非零位置。:括号生成时,左括号数不能超过n,右括号数不能超过左括号数。:LCA问题中,若左右子树均含目标节点,则当前节点为祖先。:终止条件、递归调用、返回值,如二叉树深度递归返回。:掌握虚拟头节点、递归反转、环形检测。:掌握索引操作、快慢指针、滑动窗口。:熟悉括号匹配、单调栈、层序遍历。:熟悉反转、哈希统计、回文处理。

FAQEW的博客 1819

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

【leetcode刷题】21.三数之和——Java版

欢迎订阅《leetcode》专栏

公号:一条coding 1万+

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

大一就开始这样刷题后,我成了同学们眼中的 offer 收割机

优快云 的小伙伴们,大家好,我是五一也没有闲着的二哥。 之前不是给大家分享了一份 Java 版的 LeetCode 刷题笔记嘛,很多小伙伴留言说刚好需要,对我这种大公无私的分享精神表示敬佩(嘘。 但由于时间比较紧张,PDF 版里只包含了前 50 道,所以我感觉还欠大家 250 道。所以趁着这个假期,靠着惊人的毅力,我又整理了 50 道 Java 版,从 51 道到 100 道。整理完的那一刻,真的是对天长啸, 捶胸顿足,终于舒了一口气,终于松了一口气。可怜我的右手食指,因为点击鼠标左键过于频繁,似乎有点隐

沉默王二 2万+

❤️导图整理数组4: 三数之和 相比于 两数之和 的难点, 力扣15❤️

此专栏文章是对力扣上算法题目各种方法的总结和归纳,整理出最重要的思路和知识重点并以思维导图形式呈现,当然也会加上我对导图的详解. 目的是为了更方便快捷的记忆和回忆算法重点(不用每次都重复看题解),毕竟算法不是做了一遍就能完全记住的.所以本文适合已经知道解题思路和方法,想进一步加强理解和记忆的朋友,并不适合第一次接触此题的朋友(可以根据题号先去力扣看看官方题解,然后再看本文内容). 关于本专栏所有题目的目录链接,刷算法题目的顺序/注意点/技巧,以及思维导图源文件问题请点击此链接.欢迎...

孤柒的博客 1万+

【leetcode】算法刷题汇总

本篇总结的就是刷题过程中遇到的经典题目,以及对应的数据结构算法的学习。如果想按照数据结构进行刷题,可以参考:150道基础算法分类总结(2022)更新中……

小朱小朱绝不认输的博客 1697

数据结构与算法-算法-三数之和

本文介绍了LeetCode第15题"三数之和"的解法。题目要求找出数组中所有不重复的三元组,使其和为0。核心解法是:先排序数组,然后固定一个数,将问题转化为两数之和,使用双指针法寻找解。代码示例展示了递归实现,通过dfs2函数处理三数之和,twoSum2函数处理两数之和。解题过程中需注意去重和边界条件。文章还提供了视频讲解链接,建议参考黑马程序员的详细讲解。该题比两数之和更为复杂,是需要重点掌握的中等难度算法题。

weixin_69759588的博客 860

【刷题目录1】按标签刷LeetCode热题HOT100 java题解分类汇总

1.栈 2.堆 3.贪心算法 4.排序 5.位运算 6.树 7.深度优先搜索 8.广度优先搜索 9.并查集 10.图 11.设计

乾坤未定,你我皆是黑马 3466

LeetCode 15 三数之和 Java

LeetCode 15 三数之和 Java题目描述代码 题目描述 给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。 注意:答案中不可以包含重复的三元组。 示例: 给定数组 nums = [-1, 0, 1, 2, -1, -4], 满足要求的三元组集合为: [ [-1, 0, 1], [-1, -1, 2] ] 来源:力扣(LeetCode) 链接:https://leetcode-cn.c

qq_29061435的博客 384

去面试字节前端,竟然考算法,是不是有病?算法如何刷题?全文高能!倾心整理【建议收藏!】

为什么字节跳动的前端面试需要那么难的算法题? - 知乎 昨天有个985的美女粉丝说,去面试字节的前端,竟然要考算法,搞的自己很懵逼! 插图1 面试前端,竟然要考算法!是不是脑子瓦特(water)了! 在小孟看来,这真的狠正常! 大家都知道,现在的IT行业非常的卷,都卷成啥样了,本来科班的人就很多进入了计算机行业,还有其他的专业不断的往IT行业涌入,例如生化环材一些天坑专业。 所以现在的计算机培训机构才异常的火爆!很多机构几个月竟然能把一个非科班专业的学生包装成一两年经验的开发者。 但是很多包装

程序员springmeng 8990

如何快速学习LeetCode算法:5步刷题法与五毒神掌实战指南

想要快速掌握LeetCode算法,拿到心仪的大厂offer?🚀 本文将为你揭秘一套完整的LeetCode算法学习体系,结合**五毒神掌**和**5步刷题法**,帮助你从算法小白成长为面试高手! LeetCode算法学习不仅仅是刷题,更是一种科学的训练方法。通过本指南,你将学会如何**系统化地学习算法**,掌握**数据结构与算法**的核心套路,并运用**五毒神掌**的记忆技巧形成长期记忆。无论你

gitblog_00346的博客 1052

新手基础Python、Java、C、C++、C#、Go、Php刷题LeetCode路线、思想和心得

首先给一个B站程序媛的新手刷题指南视频分享,这个视频内容不错。这篇文章主要结合视频中的精华和自己这段时间刷题的一些心得。 因为基础差以前基本没刷过LeetCode,又面临找工作,所以时间分配很重要。我的时间路线大概分为两步: 按照这个github仓库的路线进行模块化的刷题,因为以前的数据结构和算法设计都忘得差不多了,所以先分类型去刷题把每个版块的内容捡起来。刚好这个仓库能够满足需要,题量也不是太多。 刷完这个仓库上面的题之后基本上对所有题目类型都有一个了解,看到LeetCode大部分的题目都能够有一个

Alex__Mahone的专栏 2166

LeetCode 热题 HOT 100 Java题解——15. 三数之和

LeetCode 热题 HOT 100 Java题解15. 三数之和排序,双指针复杂度分析 15. 三数之和 题目: 给你一个包含 nnn 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,ca,b,ca,b,c ,使得 a+b+c=0a + b + c = 0a+b+c=0 ?请你找出所有满足条件且不重复的三元组。 注意: 答案中不可以包含重复的三元组。 示例: 给定数组 nums = [-1, 0, 1, 2, -1, -4], 满足要求的三元

qq_20067165的博客 336
上一篇: java数据结构与算法刷题-----LeetCode454. 四数相加 II
下一篇: java数据结构与算法刷题-----LeetCode18. 四数之和
ydenergy_殷志鹏
博客等级 码龄7年 5887粉丝 543原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ydenergy_殷志鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值