LeetCode题练习与总结:最接近的三数之和

一、题目

给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。

返回这三个数的和。

假定每组输入只存在恰好一个解。

二、解题思路

解决这个问题的关键在于找到一个有效的算法来遍历数组并找到三个数的组合,使得它们的和最接近目标值。这里有一个常见的解题思路,即使用双指针技巧。

以下是解决这个问题的 Java 实现步骤:

  1. 首先,对数组进行排序,这样我们可以确保在遍历数组时,我们能够以线性时间复杂度找到最接近目标值的三个数。
  2. 初始化一个变量来存储当前找到的最接近目标值的和,以及一个变量来存储当前的最小差值。
  3. 使用一个循环遍历数组(除了第一个元素),对于数组中的每个元素(称为固定元素),使用两个指针分别指向固定元素的下一个元素和数组的最后一个元素。
  4. 在每次迭代中,计算三个元素的和,并与目标值的差值进行比较。如果这个差值小于当前的最小差值,更新最小差值和最接近的和。
  5. 移动指针以尝试找到更接近目标值的组合。如果当前和大于目标值,移动较小的指针(因为它会使和减小),如果当前和小于目标值,移动较大的指针(因为它会使和增大)。
  6. 当遍历完成后,返回最接近目标值的和。

三、具体代码

import java.util.Arrays;class Solution {public int threeSumClosest(int[] nums, int target) {// Step 1: Sort the arrayArrays.sort(nums);// Step 2: Initialize variablesint closestSum = nums[0] + nums[1] + nums[nums.length - 1];int minDiff = Math.abs(target - closestSum);// Step 3: Loop through the arrayfor (int i = 0; i < nums.length - 2; i++) {// Step 4: Use two pointersint left = i + 1;int right = nums.length - 1;while (left < right) {// Step 5: Calculate the sum and find the closestint currentSum = nums[i] + nums[left] + nums[right];int currentDiff = Math.abs(target - currentSum);// Update closestSum and minDiff if necessaryif (currentDiff < minDiff) {closestSum = currentSum;minDiff = currentDiff;}// Step 6: Move pointersif (currentSum < target) {left++; // Increase sum} else if (currentSum > target) {right--; // Decrease sum} else {// We found the exact sum, break the loopbreak;}}}return closestSum;}
}

四、时间复杂度和空间复杂度

1. 时间复杂度
  • 时间复杂度是 O(n^2)。
  • 数组排序操作 Arrays.sort(nums) 的时间复杂度是 O(n log n),其中 n 是数组的长度。
  • 接下来是两层循环。外层循环遍历数组,除了第一个元素,所以最多执行 n-1 次。内层循环使用两个指针,最坏情况下会遍历整个数组,即 O(n)。因此,内层循环的时间复杂度是 O(n)。
  • 综合考虑,整个算法的时间复杂度是 O(n log n)(排序)加上 O(n^2)(双层循环),但由于 O(n^2) 通常比 O(n log n) 大得多,所以总的时间复杂度是 O(n^2)。
2. 空间复杂度
  • 空间复杂度是 O(1)。
  • 除了输入数组和一些辅助变量(如 closestSumminDiff)之外,没有使用额外的数据结构。这些辅助变量的空间需求是常数级别的。
  • 因此,空间复杂度是 O(1),即常数空间复杂度。

五、总结知识点

  1. 数组排序:使用 Arrays.sort(nums) 方法对输入的整数数组进行排序。这是解决这个问题的基础,因为排序后的数组可以使得后续的双指针算法更加高效。

  2. 双指针技巧:在排序后的数组中,通过使用两个指针(left 和 right)来遍历数组,寻找和目标值最接近的三个数。这种技巧常用于解决涉及数组和目标值比较的问题。

  3. 循环控制:代码中使用了 for 循环和 while 循环来控制算法的执行流程。for 循环用于遍历数组的每个元素,而 while 循环则用于在找到合适的三个数之前不断调整指针位置。

  4. 条件判断:在 while 循环中,通过比较当前和 currentSum 与目标值 target 的大小关系,决定是移动左指针(增加和)还是右指针(减少和)。

  5. 数学运算:使用 Math.abs(target - currentSum) 来计算当前和与目标值的绝对差值,这是确定最接近目标值的关键步骤。

  6. 变量更新:在找到更接近目标值的和时,更新 closestSumminDiff 变量。这是动态编程思想的一个体现,即在每一步中都保留当前最优解。

  7. 算法效率:代码中考虑了算法的效率,通过排序和双指针技巧,将原本可能需要 O(n^3) 时间复杂度的问题降低到了 O(n^2)。

  8. 边界条件处理:在 while 循环中,当找到和等于目标值时,使用 break 语句提前结束循环,这是一种边界条件处理,确保算法在找到最优解后不会继续执行不必要的操作。

  9. 代码可读性:代码结构清晰,注释详细,有助于理解算法的每一步。良好的代码可读性对于维护和理解代码非常重要。

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

车载电子电器架构 —— 电气架构开发计划

车载电子电器架构 —— 电气架构开发计划 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明…

实现KingSCADA系统按钮弹窗出现位置随点击位置变化。

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 在用KingSCADA做项目时&#xff0c;当我们点击不同的控制按钮&#xff0c;都可以弹出对应的控制弹窗。 在常规不做设置的情况下弹窗都是出现在固定的位置&#xff0c;要么一直出现在左上角&#xff0c;要么一直出现在…

【Java】常用实用类及java集合框架(实验六)

目录 一、实验目的 二、实验内容 三、实验小结 3.1 常用实用类 3.2 Java集合框架 一、实验目的 1、掌握java常用类的方法 2、掌握String类与数值类型数据的相互转化 3、掌握正则表达式的应用 4、掌握常用集合的创建和操作方法 二、实验内容 1、菜单的内容如下&#x…

南邮概率统计与随机过程练习册答案

**南京邮电大学** **概率统计与随机过程练习册答案简介** 本文档是一份精心整理的南京邮电大学概率统计与随机过程课程的练习册答案集。它旨在为学习该课程的学生提供一个详尽的解题参考,帮助他们更好地理解和掌握概率论与统计学的基本概念和方法。 **内容概览:** - **章节…

抖音视频评论数据提取软件|抖音数据抓取工具

一、开发背景&#xff1a; 在业务需求中&#xff0c;我们经常需要下载抖音视频。然而&#xff0c;在网上找到的视频通常只能通过逐个复制链接的方式进行抓取和下载&#xff0c;这种操作非常耗时。我们希望能够通过关键词自动批量抓取并选择性地下载抖音视频。因此&#xff0c;为…

git 拉取远程分支到本地

背景&#xff1a; 我的 github 上的远程仓库上除了 main 分支外还提交了好几个别的分支&#xff0c;现在我换机器了&#xff0c;git clone 原仓库后只剩 main 分支&#xff0c;我要把其他分支拉下来到本地。 1. 查看所有远程remote分支 git branch -r 比如我这里&#xff1…

深入浅出:探究过完备字典矩阵

在数学和信号处理的世界里&#xff0c;我们总是在寻找表达数据的最佳方式。在这篇博文中&#xff0c;我们将探讨一种特殊的矩阵——过完备字典矩阵&#xff0c;这是线性代数和信号处理中一个非常有趣且实用的概念。 什么是过完备字典矩阵&#xff1f; 首先&#xff0c;我们先…

LeetCode 2610.转换二维数组

给你一个整数数组 nums 。请你创建一个满足以下条件的二维数组&#xff1a; 二维数组应该 只 包含数组 nums 中的元素。 二维数组中的每一行都包含 不同 的整数。 二维数组的行数应尽可能 少 。 返回结果数组。如果存在多种答案&#xff0c;则返回其中任何一种。 请注意&…

多数元素

169. 多数元素 给定一个大小为 n 的数组 nums &#xff0c;返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的&#xff0c;并且给定的数组总是存在多数元素。 示例 1&#xff1a; 输入&#xff1a;nums [3,2,3] 输出&…

docker用法

首先需要去docker官网注册你的账号&#xff0c;记住账号名称和密码&#xff1b; 然后在本地执行&#xff1a; docker login登录OK。 把ubuntu下载到本地&#xff1a; sudo docker pull ubuntusudo docker images输出&#xff1a; REPOSITORY TAG …

认识K8S

K8S K8S 的全称为 Kubernetes (K12345678S) 是一个跨主机容器编排工具 作用 用于自动部署、扩展和管理“容器化&#xff08;containerized&#xff09;应用程序”的开源系统。 可以理解成 K8S 是负责自动化运维管理多个容器化程序&#xff08;比如 Docker&#xff09;的集群…

278.【华为OD机试真题】寻找最优的路测线路(二分查找—JavaPythonC++JS实现)

🚀点击这里可直接跳转到本专栏,可查阅顶置最新的华为OD机试宝典~ 本专栏所有题目均包含优质解题思路,高质量解题代码(Java&Python&C++&JS分别实现),详细代码讲解,助你深入学习,深度掌握! 文章目录 一. 题目-寻找最优的路测线路二.解题思路三.题解代码Pyt…

unity学习(40)——创建(create)角色脚本(panel)——UI

1.点击不同的头像按钮&#xff0c;分别选择职业1和职业2&#xff0c;create脚本中对应的函数。 2.调取inputfield中所输入的角色名&#xff08;限制用户名长度为7字符&#xff09;&#xff0c;但愿逆向的服务器可以查重名&#xff1a; 3.点击头衔&#xff0c;显示选择的职业&a…

【小程序】应用程序编程接口能力汇总——网络API(一)

ty.request 获取网络请求任务对象 RequestTask 参数 Object object 发起 HTTPS 网络请求的回调函数 回调参数 Object res 属性类型默认值必填说明urlstring是开发者服务器接口地址datastring否请求的参数headerany否设置请求的 header&#xff0c;header 中不能设置 Refe…

第二十篇文章——谈谈我的感受

一.契机 很早以前&#xff0c;我就使用了CSDN&#xff0c;并从很多大佬的文章中学到了很多的知识&#xff0c;当我再次从C语言开始&#xff0c;从走编程之路的时候&#xff0c;我思考&#xff1a;为什么不能把我再次学习的所思所感记录下来呢&#xff1f;因此&#xff…

vite 项目提示 Buffer is not defined 问题解决

问题 在 vite 搭建的 vue3 项目中使用 Buffer 对象报错 Buffer is not defined 原因 出现这个问题的原因是因为页面运行在浏览器中&#xff0c;而浏览器中并没有 Buffer 对象&#xff0c;Buffer 对象是 Node 中的。 解决方法 1、安装 buffer 插件 npm install buffer 2、…

SpringBootWeb请求响应

SpringBootWeb请求响应 这里写目录标题 SpringBootWeb请求响应前言1. 请求1.1 Postman1.1.1 介绍1.1.2 安装 1.2 简单参数1.2.1 原始方式1.2.2 SpringBoot方式1.2.3 参数名不一致 1.3 实体参数1.3.1 简单实体对象1.3.2 复杂实体对象 1.4 数组集合参数1.4.1 数组1.4.2 集合 1.5 …

代码随想录算法训练营|day42

第九章 动态规划 416.分割等和子集代码随想录文章详解 背包类型求解方法0/1背包外循环nums,内循环target,target倒序且target>nums[i]完全背包外循环nums,内循环target,target正序且target>nums[i]组合背包外循环target,内循环nums,target正序且target>nums[i] 416.分…

前端解析后端返回文件流格式数据

当后端接口返回数据是一个文件流数据时&#xff0c;如下后端返回给我的是一个pdf文件流数据 methods: {gotoPri() {protocolApi().then(res > {this.createPdf(res.data,XXX协议)})},createPdf(res, name) {// Blob构造函数返回一个新的 Blob 对象并指定type类型。let blob …

js设计模式:外观模式

作用: 将复杂的功能封装成可以简单调用的方法,无需知道内部的具体逻辑,只需要知道怎么去使用 类似于一把枪,你可以不知道内部的枪机,击发机,复进簧,枪管,导气装置,弹夹是怎么合作配合完成发射和自动填弹,你只需要知道你扣动扳机就能完成这一系列复杂的操作,而那个扳机就是外观…