LeetCode从低效到高效,点击
一、题目描述:
题目要求
给定一个已按照 升序排列 的整数数组 numbers ,请你从数组中找出两个数满足相加之和等于目标数 target 。函数应该以长度为 2 的整数数组的形式返回这两个数的下标值。numbers 的下标 从 1 开始计数 ,所以答案数组应当满足 1 <= answer[0] < answer[1] <= numbers.length 。你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
来源:力扣(LeetCode)链接
示例
输入:numbers = [2,7,11,15], target = 9
输出:[1,2]
解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。
二、思路分析:
本题是一道比较简单的题,但是可以从这道题延伸出双指针的思路,以及哈希表的思路.由于已经有序,所以是优先用双指针来做的,左右指针分别指向数组左右,向中心搜索,直到找到合适的解.在使用字典时注意先判断,然后再加入,防止把把自己多算了一个.
三、AC 代码:
双指针思路
vector<int> twoSum_v1(vector<int> &numbers, int target)
{
auto l = numbers.begin();
auto r = numbers.end() - 1;
while (l != r)
{
// 超过预期,说明右面的值没人配合,右指针左移
if (*l + *r > target)
{
r--;
}
// 同理,左指针右移
else if (*l + *r < target)
{
l++;
}
else
{
return vector<int>{int(distance(numbers.begin(), l)) + 1, int(distance(numbers.begin(), r)) + 1};
}
}
return {};
}
但是,上述代码还有优化空间,可以复用一些变量,最终优化成下面这样
vector<int> twoSum(vector<int> &numbers, int target)
{
unordered_map<int, int> m{};
for (int i = 0; i < numbers.size(); i++)
{
if (m.find(target - numbers[i]) != m.end())
{
return {m[target - numbers[i]] + 1, i + 1};
}
// 这里之所以先判断,再加入本次元素,是为了防止本次扫描的元素*2==target
else
{
m[numbers[i]] = i;
}
}
return {};
}
四、总结:
本题是双指针解法的开始,使用双指针还有很多题目,从这道题开始也逐渐发现精巧的解法并不唯一,要根据实际选择合适的解法.
本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情