1 题目
题目:两数和-差等于目标值(Two Sum - Difference equals to target)
描述:给定一个排序后的整数数组,找到两个数的 差 等于目标值。你需要返回一个包含两个数字的列表 [num1, num2], 使得 num1 与 num2 的差为 target,同时 num1 必须小于 num2。假设只有一个答案。要求用O(1)空间复杂度完成。
lintcode题号——610,难度——medium
样例1:
输入: nums = [2, 7, 15, 24], target = 5
输出: [2, 7]
解释:(7 - 2 = 5)
样例2:
输入: nums = [1, 1], target = 0
输出: [1, 1]
解释:(1 - 1 = 0)
2 解决方案
2.1 思路
使用同向双指针的方式,指定index1和index2,指针index2先向前走,找到与index1差值大于target的位置,然后index1再向前,直到两者差值小于target,再移动right,重复这个过程,直到找到结果。
可以将两个指针看成橡皮筋的两端,移动过程类似于扯橡皮筋。
2.2 时间复杂度
时间复杂度为O(n)。
2.3 空间复杂度
空间复杂度为O(1)。
3 源码
细节:
- 使用同向双指针的方式。
- 指针index2先向前走,找到与index1差值大于target的位置,然后index1再向前,直到两者差值小于target,再移动right,重复这个过程,直到找到结果。(就像扯橡皮筋的感觉)
- 对于index1追上index2重合情况,需要index1多向前跳一步,防止重合,index1可以超过index2。(对index2情况也一样)
C++版本:
/**
* @param nums: an array of Integer
* @param target: an integer
* @return: [num1, num2] (index1 < index2)
*/
vector<int> twoSum7(vector<int> &nums, int target) {
// write your code here
vector<int> result;
if (nums.size() < 2)
{
return result;
}
int index1 = 0;
int index2 = 1;
while (index1 < nums.size() && index2 < nums.size())
{
if (nums.at(index2) - nums.at(index1) < target)
{
index2++;
if (index1 == index2) // 当前指针再往前跳一步,防止两个指针重合
{
index2++;
}
}
else if (nums.at(index2) - nums.at(index1) > target)
{
index1++;
if (index1 == index2) // 当前指针再往前跳一步,防止两个指针重合
{
index1++;
}
}
else
{
int minIndex = min(nums.at(index1), nums.at(index2));
int maxIndex = max(nums.at(index1), nums.at(index2));
result.push_back(minIndex);
result.push_back(maxIndex);
break;
}
}
return result;
}