思路
设一元素非递减的数组示例和初始双指针 l , r l, r l,r 如下所示。
观察首尾元素 nums[
l
l
l] 和 nums[
r
r
r]。
记中间的任意数字为 mid,满足 nums[
l
l
l]
≤
\leq
≤ mid
≤
\leq
≤ nums[
r
r
r]。
- 如果 nums[ l l l] + nums[ r r r] = target,数对 (nums[ l l l], nums[ r r r]) 即为答案。
- 如果 nums[ l l l] + nums[ r r r] < target,则 nums[ l l l]+ mid < target,可舍弃 nums[ l l l],令 l l l 右移。
- 如果 nums[ l l l] + nums[ r r r] > target,则 mid + nums[ r r r] > target,可舍弃 nums[ r r r],令 r r r 左移。
此后循环分析这个过程并移动指针即可。
代码
仅提供 Java 版本,多语言代码块可详见 Leetcode 的个人题解。
class Solution {
public int[] twoSum(int[] numbers, int target) {
int l = 0;
int r = numbers.length - 1;
while (l < r) {
int sum = numbers[l] + numbers[r];
if (sum < target) {
l++;
} else if (sum == target) {
// 注意返回的下标从 1 开始
return new int[]{l + 1, r + 1};
} else {
r--;
}
}
return new int[]{}; // 这行不会执行,但需写上以通过编译。
}
}
复杂度
时间:
O
(
n
)
O(n)
O(n)
空间:
Θ
(
1
)
\Theta(1)
Θ(1)
推广
以下均为个人所著,兼顾了面试、本科、硕士阶段,包含清晰的 PPT 动画展示以及配套的练习题。读者也在陆续写其他算法教程。