# 0167. 两数之和 II \* 输入有序数组 ## 题目地址(167. 两数之和 II - 输入有序数组) <https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/> ## 题目描述 这是leetcode头号题目`two sum`的第二个版本,难度简单。 ``` <pre class="calibre18">``` 给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。 函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。 说明: 返回的下标值(index1 和 index2)不是从零开始的。 你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。 示例: 输入: numbers = [2, 7, 11, 15], target = 9 输出: [1,2] 解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。 ``` ``` ## 前置知识 - 双指针 ## 公司 - 阿里 - 腾讯 - 百度 - 字节 - amazon ## 思路 由于题目没有对空间复杂度有求,用一个hashmap 存储已经访问过的数字即可。 假如题目空间复杂度有要求,由于数组是有序的,只需要双指针即可。一个left指针,一个right指针, 如果left + right 值 大于target 则 right左移动, 否则left右移,代码见下方python code。 > 如果数组无序,需要先排序(从这里也可以看出排序是多么重要的操作) ## 关键点解析 - 由于是有序的,因此双指针更好 ## 代码 - 语言支持:JS,C++,Java,Python Javascript Code: ``` <pre class="calibre18">``` <span class="hljs-title">/** * @param {number[]} numbers * @param {number} target * @return {number[]} */</span> <span class="hljs-keyword">var</span> twoSum = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">numbers, target</span>) </span>{ <span class="hljs-keyword">const</span> visited = {} <span class="hljs-title">// 记录出现的数字, 空间复杂度N</span> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> index = <span class="hljs-params">0</span>; index < numbers.length; index++) { <span class="hljs-keyword">const</span> element = numbers[index]; <span class="hljs-keyword">if</span> (visited[target - element] !== <span class="hljs-keyword">void</span> <span class="hljs-params">0</span>) { <span class="hljs-keyword">return</span> [visited[target - element], index + <span class="hljs-params">1</span>] } visited[element] = index + <span class="hljs-params">1</span>; } <span class="hljs-keyword">return</span> []; }; ``` ``` C++ Code: ``` <pre class="calibre18">``` <span class="hljs-keyword">class</span> Solution { <span class="hljs-keyword">public</span>: <span class="hljs-params">vector</span><<span class="hljs-keyword">int</span>> twoSum(<span class="hljs-params">vector</span><<span class="hljs-keyword">int</span>>& numbers, <span class="hljs-keyword">int</span> target) { <span class="hljs-keyword">int</span> n = numbers.size(); <span class="hljs-keyword">int</span> left = <span class="hljs-params">0</span>; <span class="hljs-keyword">int</span> right = n<span class="hljs-params">-1</span>; <span class="hljs-keyword">while</span>(left <= right) { <span class="hljs-keyword">if</span>(numbers[left] + numbers[right] == target) { <span class="hljs-keyword">return</span> {left + <span class="hljs-params">1</span>, right + <span class="hljs-params">1</span>}; } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (numbers[left] + numbers[right] > target) { right--; } <span class="hljs-keyword">else</span> { left++; } } <span class="hljs-keyword">return</span> {<span class="hljs-params">-1</span>, <span class="hljs-params">-1</span>}; } }; ``` ``` Java Code: ``` <pre class="calibre18">``` <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Solution</span> </span>{ <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span>[] twoSum(<span class="hljs-keyword">int</span>[] numbers, <span class="hljs-keyword">int</span> target) { <span class="hljs-keyword">int</span> n = numbers.length; <span class="hljs-keyword">int</span> left = <span class="hljs-params">0</span>; <span class="hljs-keyword">int</span> right = n-<span class="hljs-params">1</span>; <span class="hljs-keyword">while</span>(left <= right) { <span class="hljs-keyword">if</span>(numbers[left] + numbers[right] == target) { <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-keyword">int</span>[]{left + <span class="hljs-params">1</span>, right + <span class="hljs-params">1</span>}; } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (numbers[left] + numbers[right] > target) { right--; } <span class="hljs-keyword">else</span> { left++; } } <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-keyword">int</span>[]{-<span class="hljs-params">1</span>, -<span class="hljs-params">1</span>}; } } ``` ``` Python Code: ``` <pre class="calibre18">``` <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Solution</span>:</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">twoSum</span><span class="hljs-params">(self, numbers: List[int], target: int)</span> -> List[int]:</span> visited = {} <span class="hljs-keyword">for</span> index, number <span class="hljs-keyword">in</span> enumerate(numbers): <span class="hljs-keyword">if</span> target - number <span class="hljs-keyword">in</span> visited: <span class="hljs-keyword">return</span> [visited[target-number], index+<span class="hljs-params">1</span>] <span class="hljs-keyword">else</span>: visited[number] = index + <span class="hljs-params">1</span> <span class="hljs-title"># 双指针思路实现</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Solution</span>:</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">twoSum</span><span class="hljs-params">(self, numbers: List[int], target: int)</span> -> List[int]:</span> left, right = <span class="hljs-params">0</span>, len(numbers) - <span class="hljs-params">1</span> <span class="hljs-keyword">while</span> left < right: <span class="hljs-keyword">if</span> numbers[left] + numbers[right] < target: left += <span class="hljs-params">1</span> <span class="hljs-keyword">if</span> numbers[left] + numbers[right] > target: right -= <span class="hljs-params">1</span> <span class="hljs-keyword">if</span> numbers[left] + numbers[right] == target: <span class="hljs-keyword">return</span> [left+<span class="hljs-params">1</span>, right+<span class="hljs-params">1</span>] ``` ``` **复杂度分析** - 时间复杂度:O(N)O(N)O(N) - 空间复杂度:O(1)O(1)O(1) 更多题解可以访问我的LeetCode题解仓库:<https://github.com/azl397985856/leetcode> 。 目前已经30K star啦。 关注公众号力扣加加,努力用清晰直白的语言还原解题思路,并且有大量图解,手把手教你识别套路,高效刷题。 ![](https://img.kancloud.cn/a3/63/a363818092b0356fbd67882f0389528b_900x500.jpg)