1. 题目

1.1 英文题目

Given an array of integers numbers that is already sorted in non-decreasing order, find two numbers such that they add up to a specific target number.

Return the indices of the two numbers (1-indexed) as an integer array answer of size 2, where 1 <= answer[0] < answer[1] <= numbers.length.

The tests are generated such that there is exactly one solution. You may not use the same element twice.

1.2 中文题目

一个有序数组,找到两个数和等于特定数的位置。

注意:索引从1开始并且数组中的一个元素只能用一次。

1.3输入输出

输入 输出
numbers = [2,7,11,15], target = 9 [1,2]
numbers = [2,3,4], target = 6 [1,3]
numbers = [-1,0], target = -1 [1,2]

1.4 约束条件

  • 2 <= numbers.length <= 3 * 104
  • -1000 <= numbers[i] <= 1000
  • numbers is sorted in non-decreasing order.
  • -1000 <= target <= 1000
  • The tests are generated such that there is exactly one solution.

2. 分析

2.1 暴力求解法

这一题首先可以利用暴力求解法,遍历所有可能的组合,复杂度为O(\(n^{2}\)),代码如下:

class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
vector<int> result(2);
for (int i = 0; i < numbers.size() - 1; i++)
{
for (int j = i + 1; j < numbers.size(); j++)
{
if (target - numbers[i] == numbers[j])
{
result = { ++i, ++j };
break;
}
}
}
return result;
}
};

这种方法运行效率太低,而且没有利用数组有序的条件

2.2 哈希表法

这种方法是参考leetcode第一题的解法,第一题和该题唯一的差异是第一题数组无序,因此第一题的哈希表法同样适用于本题,但是没有利用到数组有序的条件,非最优,时间复杂度为O(n)。代码如下:

class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
// 哈希表
map<int, int> hashMap;
vector<int> ans;
int temp = 0;
for (int i = 0; i < numbers.size(); i++)
{
temp = target - numbers[i];
if (hashMap.count(temp))
{
ans = { ++hashMap[temp], ++i };
break;
}
hashMap[numbers[i]] = i;
}
return ans;
}
};

2.3 二分法

遍历一个,查找另一个,而数组又是有序的,很容易想到二分法,时间复杂度为O(\(nlogn\))。具体代码如下:

class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
//二分法
vector<int> result;
for (int i = 0; i < numbers.size() - 1; i++)
{
int second = target - numbers[i];
int left = i + 1;
int right = numbers.size() - 1;
while (left <= right)
{
int mid = (left + right) / 2;
if (second < numbers[mid])
right = mid - 1;
else if (second > numbers[mid])
left = mid + 1;
else
{
result.push_back(++i);
result.push_back(++mid);
break;
}
if (result.size() == 2)
break;
}
}
return result;
}
};

2.4 头尾指针法

该方法特别秒,利用两个指针分别指向头尾,通过头尾数之和和目标数进行比较,前者大则尾指针左移,前者小则指针右移。充分利用了排好序数组这一特性,时间复杂度为O(n),代码如下:

public:
vector<int> twoSum(vector<int>& numbers, int target) {
vector<int> result;
int head = 0;
int tail = numbers.size() - 1;
while (head < tail)
{
int tempAdd = numbers[head] + numbers[tail];
if (tempAdd < target)
head++;
else if (tempAdd > target)
tail--;
else
{
result = { ++head, ++tail };
break;
}
}
return result;
}
};

参考:https://www.jianshu.com/p/f3a8a247f4c8

最新文章

  1. BZOJ2006——[NOI2010]超级钢琴
  2. React 高级指南小记
  3. TCP协议学习记录 (三) Ping程序 RR选项 记录路由hop
  4. mysql tinyint
  5. JavaScript for循环里边异步操作问题。
  6. Enclosure POJ
  7. UIMenuController的使用
  8. 推荐资料——最受网友力荐的30份HTML前端开发资料
  9. 在Mac OS X中使用VIM开发STM32(2)
  10. Open-source Project官方地址
  11. FZU1862(线段树 或者 DP)
  12. HTML5 按字母顺序排列的标签列表 new : HTML5 中的新标签。
  13. 大约C++ const 全面总结
  14. javascript 模块化编程 1
  15. ubuntu vi编辑insert时上下左右建为ABCD
  16. redis入门(05)redis的key命令
  17. IP地址和MAC地址的关系
  18. 2142: 逛超市(zznuoj)
  19. Hadoop权威指南
  20. Simple2D-16(音乐播放器)ImGui 库介绍

热门文章

  1. 【遥感数字图像处理实验】Erdas版详细图文实验教程(8实验全)
  2. java为什么是一次编译,多次解释
  3. web容器获取SSL指纹实现和ByPass
  4. Linux - fuser 命令
  5. 死磕nginx系列
  6. Tensor基础实践
  7. TensorFlow创建DeepDream网络
  8. 共享CUDA内存
  9. CVPR2020:点云分类的自动放大框架PointAugment
  10. 聊一聊.NET Core结合Nacos实现配置加解密