给一个数组,和一个值,要求返回两数相加等于目标值的下标
思路:循环,取差,如果数组包含差值返回下标,否则下一轮循环
// 使用for + indexOf
function sum (arr, target) {
for (let i = 0; i < arr.length; i++) {
let min = target - arr[i];
let index = arr.indexOf(min);
if (index > -1 && index !== i) {
return [i, index];
}
}
}
// 使用循环+对象的方法
function sum (arr, target) {
let res = {};
for (let i = 0; i < arr.length; i++) {
let min = target - arr[i];
if (min in res) {
return [res[min], i];
}
res[arr[i]] = i;
}
}
进阶版,有序数组,求两数和,使用双指针
function sum (arr, target) {
let i = 0,
j = arr.length - 1;
while (i < j) {
if (arr[i] + arr[j] === target) {
return [i, j];
} else if (arr[i] + arr[j] < target) { // 如果和比target小,i右移
i++;
} else { // 反之 j 左移
j--;
}
}
}
再改版,求有序数组上限和,给一个目标值target,返回最两数相加最接近target的下标
// 类似二分法 target / 2, for数组中找 最接近 t/2的两个数
function sumTwo (arr, target) {
let k = target / 2;
for (let i = 1; i < arr.length; i++) {
if (arr[i - 1] - k <= 0 && arr[i] - k >= 0) {
return [i - 1, i];
}
}
}
// 双指针法,先尽量将j左移
function sumTwo (arr, target) {
let resi = 0,
resj = 0,
max = 0,
i = 0,
j = arr.length - 1;
while (arr[i] + arr[j] > target && i < j) { // 第一次循环 如果头尾相加大于target,j左移动
j--; // j左移可以缩短下次循环数组的长度
}
while (arr[i] + arr[j] <= target && i < j) { // 第二次循环
if (arr[i] + arr[j] > max) { // 如果本次和大于上次和,保存 i, j, 和max
resi = i;
resj = j;
max = arr[i] + arr[j];
}
i++;
if (arr[i] + arr[j] > target && i < j) {
j--;
}
}
return [resi, resj, max];
}
https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/solution/js-xie-leetcode-by-zhl1232-21/
https://www.cnblogs.com/echolun/p/12961904.html