双指针 - 两数之和 & 两数平方和
Posted GoldenaArcher
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了双指针 - 两数之和 & 两数平方和相关的知识,希望对你有一定的参考价值。
双指针 - 两数之和 & 两数平方和
题目地址: Leetcode 题解 - 双指针
这里做第一题和第二题:
-
有序数组的 Two Sum
-
两数平方和
这两题的题目类型和解题思路都很像,因此就放在一起了。
有序数组的 Two Sum
题目:
给定一个已按照 升序排列 的整数数组
numbers
,请你从数组中找出两个数满足相加之和等于目标数target
。函数应该以长度为
2
的整数数组的形式返回这两个数的下标值。numbers
的下标 从 1 开始计数 ,所以答案数组应当满足1 <= answer[0] < answer[1] <= numbers.length
。你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
解题思路:
-
已知整数数组是 升序排列
-
需要找出两个数字,相加之和等于目标
target
-
下标 从 1 开始计数
会特地标注下标从 1 开始是因为数组正常数组下标从 0 开始,而本题需要返回的值是以 1 做起始点
-
你可以假设每个输入只对应唯一的答案
这用英文理解起来其实更容易:
The tests are generated such that there is exactly one solution.
也就意味着每道问题有唯一解
-
提示为双指针,即一个 pointer left 指向最左边,一个 pointer right 指向最右边
在已知每道题有唯一解的情况下,当 a r r a y [ l e f t ] + a r r a y [ r i g h t ] = t a r g e t array[left] + array[right] = target array[left]+array[right]=target 时,需要返回
[left+1, right+1]
即可当 a r r a y [ l e f t ] + a r r a y [ r i g h t ] < t a r g e t array[left] + array[right] < target array[left]+array[right]<target 时,也就代表着
array[left]
的数值小了,将指针 left 向右移动一格当 a r r a y [ l e f t ] + a r r a y [ r i g h t ] > t a r g e t array[left] + array[right] > target array[left]+array[right]>target 时,也就代表着
array[right]
的数值大了,将指针 right 向左移动一格
根据解题思路解题:
/**
* @param {number[]} numbers
* @param {number} target
* @return {number[]}
*/
var twoSum = function (numbers, target) {
// 检查边界条件
if (!numbers || !numbers instanceof Array) {
throw 'numbers muse be an array';
}
if (numbers.length < 2) {
throw 'the length of numbers must be greater than 2';
}
// 先确立双指针
let left = 0,
right = numbers.length - 1;
while (left < right) {
// 当找到了 target
if (numbers[left] + numbers[right] === target) {
// 记住是 以 1 做起始点
// 数组是 0-indexed,所以返回值需要+1
return [left + 1, right + 1];
}
// 左边的值小了
else if (numbers[left] + numbers[right] < target) {
left++;
}
// 右边的值大了
else {
right--;
}
}
// 加一个返回值,这个情况下就是找不到 两数之和
// 题目中尽管说是保证会有,不过正常开发碰到这种情况还是需要处理的
throw 'solution not found';
};
两数平方和
题目:
给定一个非负整数
c
,你要判断是否存在两个整数a
和b
,使得 a 2 + b 2 = c a^2 + b^2 = c a2+b2=c 。
解题思路:
这题的风格其实和 有序数组的 Two Sum 很像,上一题中的数组这一题可以理解成: [ 1 , 2 , 3 , . . . , c ] [1, 2, 3, ..., \\sqrt{c}] [1,2,3,...,c] 这样一组数组。
接着再嵌套 有序数组的 Two Sum 的解题思路即可。
本题独有的条件有一个:
-
给定一个非负整数
c
c
必须要是正整数
根据解题思路解题:
/**
* @param {number} c
* @return {boolean}
*/
var judgeSquareSum = function (c) {
if (c <= 0) {
throw 'value must be a positive integer';
}
// 刚开始用的是 1,然后发现有几个测试没过
// 因为自己审题不清楚,题目的要求:是否存在两个整数
// 0也是整数,只不过不是正整数
let lo = 0,
hi = Math.floor(Math.sqrt(c));
// 这里也同理,是否存在两个整数,题目中也没规定两个整数是否一致
// 下面的逻辑判断与上一题一致
while (lo <= hi) {
if (lo ** 2 + hi ** 2 === c) {
return true;
} else if (lo ** 2 + hi ** 2 < c) {
lo++;
} else {
hi++;
}
}
return false;
};
没能一次 AC 的反思:
-
审题还是要审清楚,自己刷 Leecode 的时候没人问,没办法,但是在面试的时候,像这些条件一定要问清楚
-
做题目的时候一定要小心,不能带有惯性思维
这题的要求是 两数的平方和,直接做完上面两数之和再做这题就忘了平方这件事情了
以上是关于双指针 - 两数之和 & 两数平方和的主要内容,如果未能解决你的问题,请参考以下文章