解密N数之和问题的秘密

目录

    • 两数之和
    • 三数之和

在这里插入图片描述

两数之和

我们来看力扣第一题
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。

示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
输入:nums = [3,2,4], target = 6
输出:[1,2]
示例 3:
输入:nums = [3,3], target = 6
输出:[0,1]

这个题我们看到之后想到最简单的思路就是两个for循环,里层数加外层数之和等于目标数,我们就返回两个下标。

  public int[] twoSum(int[] nums, int target) {
        // 遍历数组
        for (int i = 0; i < nums.length; i++) {
            // 内层循环从i+1开始,因为i已经试过
            for (int j = i+1; j < nums.length; j++) {
                // 如果两个数相加等于target,则返回下标
                if(nums[i] + nums[j] == target){
                    return new int[]{i,j};
                }
            }
        }
        // 如果没有找到,则返回空数组
        return new int[0];
    }

但是这个解法的时间复杂度很高,我们还有更好的方法就是使用哈希表,这种方式我们可以把寻找target-x的时间复杂度由O(N)变为O(1)。
对于每一个x,我们可以先在哈希表中查找是否存在target-x,如果不存在即可把x放入哈中,这样可以避免与自己相遇。
代码实现如下:

public int[] twoSum1(int[] nums, int target) {
        // 创建一个HashMap
        HashMap<Integer,Integer> map =  new HashMap<>();
        // 遍历数组
        for (int i = 0; i < nums.length; i++) {
            // 如果HashMap中包含target-nums[i],则返回该值和i
            if(map.containsKey(target - nums[i])){
                return new int[]{ map.get(target-nums[i]),i};
            }
            // 将nums[i]作为key,i作为value,放入HashMap中
            map.put(nums[i],i);
        }
        // 如果没有找到,则返回一个空数组
        return new int[0];
    }

三数之和

我们来看力扣15题的描述
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请
你返回所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。

示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。
示例 2:
输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。
示例 3:
输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。

这道题使用三个for循环时间复杂度太高了不可取,我们使用排序加双指针来做这道题。

 public List<List<Integer>> threeSum(int[] nums) {
        int n = nums.length;
        Arrays.sort(nums);
        List<List<Integer>> ans = new ArrayList<>();
        //枚举a
        for (int first = 0; first < n; first++) {
            //和上一次的枚举数不相同
            if (first > 0 && nums[first] == nums[first - 1]) {
                continue;
            }
            int third = n - 1;
            int target = -nums[first];
            //枚举b
            for (int second = first + 1; second < n; second++) {
                if (second > first + 1 && nums[second] == nums[second - 1]) {
                    continue;
                }
                //保证b的指针在c的指针的左侧
                while (second < third && nums[second] + nums[third] > target) {
                    third--;
                }
                if (second == third) {
                    break;
                }
                if (nums[second] + nums[third] == target) {
                    List<Integer> list = new ArrayList<>();
                    list.add(nums[first]);
                    list.add(nums[second]);
                    list.add(nums[third]);
                    ans.add(list);
                }
            }

        }
        return ans;
    }
  1. 首先,对输入的数组进行排序。这样可以保证在后续的查找过程中,相邻的元素是有序的,便于排除重复的情况。
  2. 初始化一个空的答案列表,用于存储满足条件的三元组。
  3. 枚举数组的第一个元素作为第一个指针(a),第二个元素作为第二个指针(b),最后一个元素作为第三个指针(c)。
  4. 在枚举a的过程中,如果发现a和上一次枚举的元素相同,则跳过此次循环,继续枚举下一个不同的元素。
  5. 在枚举b的过程中,如果发现b和上一次枚举的元素相同,则跳过此次循环,继续枚举下一个不同的元素。
  6. 在枚举b的过程中,保证b的指针在c的指针的左侧。
  7. 当b指针小于c指针时,判断当前元素之和是否等于目标值。如果等于目标值,则将当前三元组添加到答案列表中。
  8. 继续枚举a和b,直到所有可能的组合都被检查完毕。
  9. 返回答案列表。

还有更多好玩的题目例如:四数之和等等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/145746.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【MATLAB源码-第76期】基于matlab的OCDM系统在AWGN信道下理论误码率和实际误码率对比仿真。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 正交线性调频分频复用&#xff08;OCDM&#xff0c;Orthogonal Chirp Division Multiplexing&#xff09;是一种无线通信技术&#xff0c;它基于啁啾信号的原理。啁啾信号是一种频率随时间变化的信号&#xff0c;通常频率是线…

【Java】集合(三)Map

1.Map 接口实现类的特点 1)Map与Collection并列存在。用于保存具有映射关系的数据:Key-Value 2)Map 中的 key 和 value 可以是任何引用类型的数据&#xff0c;会封装到HashMap$Node对象中 3)Map 中的 key 不允许重复 4)Map 中的 value 可以重复 5)Map 的key 可以为 null,va…

执行力太差的人,如何才能提高执行力?

执行力是计划的落地执行&#xff0c;是按照计划稳步推进&#xff0c;导向结果的能力。不同的人&#xff0c;其执行力有很大的差别。比如说有拖延症的人&#xff0c;基本上是谈不上执行力的&#xff0c;执行力是一个综合体&#xff0c;是多个要素的共同作用。 在企业HR人才测评…

java实现快速排序

图解 快速排序是一种常见的排序算法&#xff0c;它通过选取一个基准元素&#xff0c;将待排序的数组划分为两个子数组&#xff0c;一个子数组中的元素都小于基准元素&#xff0c;另一个子数组中的元素都大于基准元素。然后递归地对子数组进行排序&#xff0c;直到子数组的长度为…

Flutter的Widget, Element, RenderObject的关系

在Flutter中&#xff0c;Widget&#xff0c;Element和RenderObject是三个核心的概念&#xff0c;它们共同构成了Flutter的渲染流程和组件树的基础。下面简要介绍它们之间的关系&#xff1a; 1.Widget Widget是Flutter应用中的基础构建块&#xff0c;是一个配置的描述&#xf…

基于ssm酒店管理系统

基于ssm酒店管理系统 摘要 基于SSM&#xff08;Spring Spring MVC MyBatis&#xff09;框架的酒店管理系统是一种利用现代化技术手段来提高酒店管理效率和服务质量的信息化管理系统。该系统整合了Spring框架的依赖注入、Spring MVC框架的请求处理和MyBatis框架的持久化操作&a…

50.批处理脚本(2/2)

目录 一、批处理命令。 &#xff08;1&#xff09;net use 连接共享文件夹或查看。 &#xff08;1.1&#xff09;连接共享文件夹。 &#xff08;1.2&#xff09;断开连接。 &#xff08;1.3&#xff09;显示当前连接。 &#xff08;1.4&#xff09;查看电脑的共享文件夹。…

基于SpringBoot+Vue的宿舍管理系统

基于SpringBootVue的学生宿舍管理系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatisVue工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 主页 宿舍公告 登录界面 管理员界面 维修人员 商家界面 学生界面 摘要 摘…

VS项目属性变量

VS项目属性变量 $(SolutionDir) 获取解决方案的路径 $(Platform) 平台名字 → x86 / x64 $(ProjectName) 工程名字 $(Configuration) 当前的项目模式 → Debug / Release

基于SSM+Vue的健身房管理系统

基于SSMVue的健身房管理系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringMyBatisSpringMVC工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 主页 课程信息 健身器材 管理员界面 用户界面 摘要 健身房管理系统是一种利用现…

腾讯云4核8G和2核4G服务器五年优惠价格表

腾讯云百科整理五年云服务器优惠活动 txybk.com/go/txy 配置可选2核4G和4核8G&#xff0c;公网带宽可选1M、3M或5M&#xff0c;系统盘为50G高性能云硬盘&#xff0c;标准型S5实例CPU采用主频2.5GHz的Intel Xeon Cascade Lake或者Intel Xeon Cooper Lake处理器&#xff0c;睿频3…

NOIP 2017 宝藏----Java题解

目录 NOIP 2017 宝藏 题目描述 输入描述: 输出描述: 输入 输出 说明 输入 输出 说明 备注: 代码实现&#xff1a; NOIP 2017 宝藏 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO For…

viple模拟器使用(一):线控模拟

(1)unity模拟器 通过viple程序&#xff0c;将viple编写逻辑运行在unity模拟器中。 首先编写viple程序&#xff0c;逻辑&#xff1a;设置一个机器人主机&#xff0c;并且&#xff0c;按↑、↓、←、→方向键的时候&#xff0c;能分别控制模拟机器人在unity模拟器中运行。 主机…

【Linux基础IO篇】深入理解文件系统、动静态库

【Linux基础IO篇】深入理解文件系统、动静态库 目录 【Linux基础IO篇】深入理解文件系统、动静态库再次理解文件系统操作系统内存管理模块&#xff08;基础&#xff09;操作系统如何管理内存 Linux中task_struct源码结构 动态库和静态库动静态库介绍&#xff1a;生成静态库库搜…

学Diffusion前需要储备的一些知识点

自学Diffusion是非常困难的&#xff0c;尤其是到了VAE和VI这里基本找不到比较好的中文资料&#xff0c;甚至是涉及到一些重参数化&#xff0c;高斯混合之类的问题摸不着来龙去脉。在本文中&#xff0c;基本不会涉及公式&#xff0c;只有intuition和理解&#xff0c;如果要看公式…

NC 56 单据接口报错排查一例

前言 自从公司的古董 NC ERP 接入了共享财务系统、我们就开始了漫长的排障生涯。下面分享一例接口数据报错的分析和处理方案。 操作环境 NC 客户端是 windows 的 V56 版本。生产环境数据库是 oracle 、数据库访问用了 PL/SQL。 验证过程 早上接到了共享财务系统的报错&…

从流程优化到经营提效,法大大电子签全面助力智慧零售升级

在新零售模式下&#xff0c;“商业综合体、百货商场、连锁商超、连锁便利店、线上电商平台”等各类商业零售企业借助数字化的手段来改造和重塑传统零售流程和逻辑&#xff0c;实现全面数字化转型&#xff0c;包括线上线下一体化、全场景覆盖、全链条联通、全渠道经营、客户服务…

保序回归:拯救你的校准曲线(APP)

保序回归&#xff1a;拯救你的校准曲线&#xff08;APP&#xff09; 校准曲线之所以是评价模型效能的重要指标是因为&#xff0c;校准曲线衡量模型预测概率与实际发生概率之间的一致性&#xff0c;它可以帮助我们了解模型的预测结果是否可信。一个理想的模型应该能够准确地预测…

快乐数问题

编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为&#xff1a; 对于一个正整数&#xff0c;每一次将该数替换为它每个位置上的数字的平方和。 然后重复这个过程直到这个数变为 1&#xff0c;也可能是 无限循环 但始终变不到 1。 如果这个过程 结果为 1&#xff…

如何在Photoshop 中创建橡皮图章效果

如何在 Photoshop 中制作橡皮图章。只需几个快速步骤即可将任何照片变成橡皮图章图像 1. 如何创建垃圾纸背景 步骤1 让我们开始学习如何制作自定义印章。创建一个新的850 x 550 像素 文档。当然&#xff0c;您可以为 PSD 文件使用其他尺寸&#xff0c; 但必须按比例调整本教程…