当前位置:网站首页>LeetCode 练习——关于查找数组元素之和的两道题
LeetCode 练习——关于查找数组元素之和的两道题
2022-07-30 18:02:00 【SK_Jaco】
1. 数组中和为 0 的三个数
1.1 题目描述
给定一个已按照 升序排列 的整数数组 numbers ,请你从数组中找出两个数满足相加之和等于目标数 target 。
函数应该以长度为 2 的整数数组的形式返回这两个数的下标值。numbers 的下标 从 0 开始计数 ,所以答案数组应当满足 0 <= answer[0] < answer[1] < numbers.length 。
假设数组中存在且只存在一对符合条件的数字,同时一个数字不能使用两次。
示例 1:
输入:numbers = [1,2,4,6,10], target = 8
输出:[1,3]
解释:2 与 6 之和等于目标数 8 。因此 index1 = 1, index2 = 3 。
示例 2:
输入:numbers = [2,3,4], target = 6
输出:[0,2]
示例 3:
输入:numbers = [-1,0], target = -1
输出:[0,1]
1.2 解题思路与代码
1.2.1 解题思路
这道题是求数组中是否存在两个数字等于给定数字,可以考虑是有暴力解两层循环遍历数组依次求和,但是这一样时间复杂度是 O(n^2) 太高了。题目已经规定了数组是按升序排序的数组,我们便可以使用双指针从两边往中间移动计算两个指针指向数字之和,再与 target 进行比较移动。首先让左指针 l 指向角标 0 位置,右指针 r 指向数组最后一位,然后计算两个指针指向数字之和,此时计算的和会出现以下三种情况:
- 如果和等于 target 退出循环并返回 l 和 r(因为题目规定有且仅有一个答案)
- 如果和小于 target,因为数组从小到大排序,此时让左指针向右移动这样能够让两数之和变大
- 同理如果和大于 target,此时让右指针向左移动,这样让两数之和变小
以题目示例 numbers = [1,2,4,6,10], target = 8 为例进行图解:
首先让 l 和 r 指向首位,此时 l 和 r 指向数之和为 11,大于 target ,因此让 r 左移
r 左移之后,此时 l=0,r=3,两数之和为 7 ,小于 target 于是让 l 右移
l 右移之后,此时 l=1,r=3,两数之和为 8 ,等于 target 满足题意返回 [1, 3]
1.2.2 代码
class Solution {
public int[] twoSum(int[] numbers, int target) {
int l = 0;
int r = numbers.length - 1;
int[] ans = new int[2];
while (l < r) {
if (numbers[l] + numbers[r] == target) {
ans[0] = l;
ans[1] = r;
break;
} else if (numbers[l] + numbers[r] < target) {
l++;
} else {
r--;
}
}
return ans;
}
}
1.2.3 测试结果
通过测试
2. 数组中和为 0 的三个数
2.1 题目描述
剑指 Offer II 007. 数组中和为 0 的三个数
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a ,b ,c ,使得 a + b + c = 0 ?请找出所有和为 0 且 不重复 的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
示例 2:
输入:nums = []
输出:[]
示例 3:
输入:nums = [0]
输出:[]
2.2 解题思路与代码
2.2.1 解题思路
这道题和上面那道题其实是一样的,只不过从两数之和为 target 变成了三数之和为零。我们可以转换一下思想,如果我们抓住数组中一个数字 num,然后就编程在剩下的数字中找到两个数的和等于 -num。我们在进一步,对数组 nums 进行排序,然后我们从左到右遍历数组:
- 遍历第一位 nums[0] 时,我们就需要在 [1, n-1] 的范围上寻找两个数的和等于 -num[0]
- 遍历到第二位 nums[1] 时,我们就需要在 [2, n-1] 的范围上寻找两个数的和等于 -num[1]
- 遍历到第三位 nums[2] 时,我们就需要在 [3, n-1] 的范围上寻找两个数的和等于 -num[2]
…… - 依次类推
由于我们已经对数组进行排序,那么在后面查找范围内的数字均是按升序排序的,到这里就能够看出和上面那道题是一模一样的了,只不过 target 变成了 -nums[i],查找范围变成 [i+1, n-1]。从上面的分析,我们可以在外层循环遍历数组,循环内部使用双指针从 [i+1, n-1] 的范围上查找两数之和等于 -num[i] 的两个数。与上面题目相同,也有三种情况:
- 当两数之和小于 -num[i] 时,l 右移
- 当两数之和大于 -num[i] 时,l 左移
- 当两数之和等于 -num[i] 时,i、l、r 三个位置上的数字放入结果列表中,然后 l 右移、r 左移。
这里需要注意,题目要求不能出现重复的数字,因此当 nums[i] 等于 nums[i-1] 时,跳过本次循环,同理 nums[l] 等于 nums[l-1]、 nums[r] 等于 nums[r+1] 时也需要跳过。下面是数组 [-1,0,1,2,-1,-4] 查找的过程,首先 i=0,我们使用 l 和 r 在 [1, 5] 的范围上查找两数之和等于 4 的两个数,当 l 等于 r 时推出内层循环。然后 i=1 此时在 [2, 5] 的范围上查找两数之和等于 1 此时 l=2 和 r=5 所指的两个数之和等于 1 满足条件,放入结果数组中。接下来重复上面过程,直到数组遍历完成。
2.2.2 代码
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> ans = new ArrayList<>();
if (nums.length == 0) {
return ans;
}
Arrays.sort(nums);
for (int i = 0; i < nums.length - 2; i++) {
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
int target = -nums[i];
int l = i + 1;
int r = nums.length - 1;
while (l < r) {
if (nums[l] + nums[r] == target) {
ans.add(Arrays.asList(nums[i], nums[l], nums[r]));
do {
l++;
} while (l < r && nums[l] == nums[l - 1]);
do {
r--;
} while (l < r && nums[r] == nums[r + 1]);
} else if (nums[l] + nums[r] < target) {
l++;
} else {
r--;
}
}
}
return ans;
}
}
2.2.3 测试结果
通过测试
3.总结
- 第一题使用双指针进行处理,两数之和小于目标,左指针右移;大于目标,右指针左移;等于目标,退出循环返回结果
- 第二题是第一题的变种,排序后遍历数组,同样是在后面的数组中查找两数之和等于某一个数
- 第二题由于需要去重,因此三个指针 i、l、r 如果移动之后等于移动之前的数,那么需要继续移动
边栏推荐
- Quickly build an e-commerce platform based on Amazon cloud technology serverless service - performance
- Wincc报表教程(SQL数据库的建立,wincc在数据库中保存和查询数据,调用Excel模板把数据保存到指定的位置和打印功能)
- Kettle--MySQL生产数据库千万、亿级数据量迁移方案及性能优化
- 【HarmonyOS】【ARK UI】HarmonyOS ets语言怎么实现双击返回键退出
- 【HarmonyOS】【FAQ】鸿蒙问题合集4
- PyTorch 猫狗分类源代码及数据集
- layaBox---TypeScript---接口
- 使用postman调接口报Content type ‘text/plain;charset=UTF-8‘ not supported
- ESP8266-Arduino编程实例-HC-SR04超声波传感器驱动
- 5 个开源的 Rust Web 开发框架,你选择哪个?
猜你喜欢
随机推荐
Test the.net text to Speech module System. Researched
沃尔沃中国的年中总结,在“安全感”中寻找未来
什么是工业射线照相设备?
Leetcode数据库系列题解合集(持续更新)
分布式消息队列平滑迁移技术实战
MySQL中的存储过程(详细篇)
微博广告分布式配置中心的构建与实践(有彩蛋)
Mathematical Principles of Graph Convolutional Neural Networks——A Preliminary Study on Spectral Graph Theory and Fourier Transform
编曲软件FL Studio中文版安装教程及切换语言教程
【HMS Core】【FAQ】运动健康、音频编辑、华为帐号服务 典型问题合集7
【AGC】增长服务2-应用内消息示例
Kettle--MySQL生产数据库千万、亿级数据量迁移方案及性能优化
Confluence OGNL注入漏洞复现(CVE-2022-26134)
UE5第一人称射击游戏蓝图教程
自动化早已不是那个自动化了,谈一谈自动化测试现状和自我感受……
知识蒸馏2:目标检测中的知识蒸馏
Ecplise执行C语言报错:cannot open output file xxx.exe: Permission denied
linux 下MySQL本地安装mysql - u root - p 无法登入
信息学奥赛一本通 1915:【01NOIP普及组】最大公约数与最小公倍数 | 洛谷 P1029 [NOIP2001 普及组] 最大公约数和最小公倍数问题
Linux-安装MySQL(详细教程)