剑指 Offer 57. 和为 S 的两个数字
题目
输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。
实例1:
1 |
|
实例2:
1 |
|
解题思路:
利用HashMap可以通过遍历数组找到数字组合,时间和空间复杂度均为O(N) ;
注意本题的nums是排序数组,因此可使用双指针法将空间复杂度降低至0(1)。
算法流程:
- 初始化:双指针i, j分别指向数组nums的左右两端(俗称对撞双指针)。
- 循环搜索:当双指针相遇时跳出;
- 计算和s= nums[i] + nums[j] ;
- 若s> target,则指针j向左移动,即执行j= j-1 ;
- 若s< target,则指针i向右移动,即执行i=i+1 ;
- 若s= target,立即返回数组[nums[i], nums[j]] ;
- 返回空数组,代表无和为target的数字组合。
正确性证明:
1 |
|
- 状态S(i,j) 切换至S(i+1,j),则会消去一行元素,相当于消去了状态集合{S(i,i+
1),S(i,i + 2…(.j-.2), S(i;,j- 1),S(i,j)}。(由于双指针都是向中间收缩, 因此这些状
态之后不可能再遇到)。 - 由于nums是排序数组,因此这些消去的状态都一 定满足S(i,j) < target,即这些状态都不
是解。 - 结论:以上分析已证明“每次指针i的移动操作,都不会导致解的丢失”,即指针i的移动操
作是安全的;同理,对于指针j可得出同样推论;因此,此双指针法是正确的。
代码
1 |
|
剑指 Offer 57. 和为 S 的两个数字
http://lhystutest.top/2023/03/20/算法/剑指offer/和为s的两个数字/