算法入门 02二分查找(简单 - 第四题)LeetCode 167
Posted 英雄哪里出来
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法入门 02二分查找(简单 - 第四题)LeetCode 167相关的知识,希望对你有一定的参考价值。
一、题目
1、题目描述
给定一个升序排列的数组长度为 n ( n ≤ 1 0 4 ) n(n \\le 10^4) n(n≤104) 的整数数组 n u m b e r s numbers numbers ,要求从数组中找出两个数满足相加之和等于目标数 t a r g e t target target 。返回这两个数的下标(假设下标从 1 开始,并且答案一定存在,且不能用相同元素)。
样例: n u m b e r s = [ 2 , 5 , 11 , 19 ] numbers = [2,5,11,19] numbers=[2,5,11,19], target = 13,输出 [ 1 , 3 ] [1, 3] [1,3]
2、基础框架
- c++ 版本给出的基础框架代码如下,输入数组参数类型是
vector<int>
,返回参数也是一个数组vector<int>
,按照题目要求,需要返回一个长度为 2 的数组;
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
}
};
3、原题链接
二、解题报告
1、思路分析
首先,我们一定可以通过两层枚举 i i i 和 j j j ( i < j ) (i \\lt j) (i<j),然后判断
numbers[i] + numbers[j] == target
是否成立,如果成立,那么 [ i + 1 , j + 1 ] [i+1, j+1] [i+1,j+1] 就是我们要求的答案了。但是这么做,时间复杂度是 O ( n 2 ) O(n^2) O(n2) 的。
然而, 考虑到数组有序,第二层循环我们可以采用二分查找降低时间复杂度,继续考虑等式:numbers[i] + numbers[j] == target
,假设第一层循环枚举后, i i i 成为已知数, j j j 成为未知数,那么,我们可以得到:numbers[j] == target - numbers[i]
,而且 j j j 的范围已知,于是可以通过二分查找数组numbers
,找到这个 j j j 的位置。
2、时间复杂度
- 第一层枚举 O ( n ) O(n) O(n),第二层二分查找 O ( l o g 2 n ) O(log_2n) O(log2n),两个操作是乘的关系,所以总的时间复杂度为 O ( n l o g 2 n ) O(nlog_2n) O(nlog2n)。
3、代码详解
class Solution {
public:
int find(vector<int>& numbers, int indexStart, int target) { // (1)
int l = indexStart;
int r = numbers.size() - 1;
while(l <= r) {
int mid = (l + r) >> 1;
if(target == numbers[mid]) {
return mid;
}else if(target > numbers[mid]) {
l = mid + 1;
}else {
r = mid - 1;
}
}
return -1;
}
vector<int> twoSum(vector<int>& numbers, int target) {
vector <int> ans;
for(int i = 0; i < numbers.size(); ++i) { // (2)
int x = find(numbers, i+1, target - numbers[i]);
if(x != -1) {
ans.push_back(i + 1); // (3)
ans.push_back(idx + 1);
return ans;
}
}
return ans;
}
};
-
(
1
)
(1)
(1)
int find(vector<int>& numbers, int indexStart, int target)
实现的是二分查找函数,查找的是从数组numbers
的indexStart
下标开始到结尾中存在的target
所在的下标,不存在则返回-1
; -
(
2
)
(2)
(2) 枚举数组
numbers
的每个位置i
,期望找到numbers[i] + numbers[x] = target
,其中 x x x 是未知数,需要我们求的,并且它满足 x > i x \\gt i x>i,由于数组有序,就可以用二分查找了,二分查找的值就是target - numbers[i]
。 -
(
3
)
(3)
(3) 得到的
x
x
x 如果不为
-1
,那么 i i i 和 x x x 就是两个满足题意的目标,又因为题目要求下标从 1 开始,所以都加上 1; - 关于二分查找的内容,可以参考这个题:【算法专题(01)二分查找(01) 简单】LeetCode 704
三、本题小知识
将一个本来已经实现的功能提出来,让调用方去调用,能够大大的增加代码的可读性,这就是面向函数编程;
以上是关于算法入门 02二分查找(简单 - 第四题)LeetCode 167的主要内容,如果未能解决你的问题,请参考以下文章
⭐算法入门⭐《二分枚举》中等02 —— LeetCode 面试题 10.09. 排序矩阵查找
⭐算法入门⭐《二分枚举》简单06 —— LeetCode 34. 在排序数组中查找元素的第一个和最后一个位置