发布于 

剑指Offer.57-和为s的两个数字

剑指Offer.57-和为s的两个数字

题目链接

<剑指 Offer 57. 和为s的两个数字 - 力扣(LeetCode) (leetcode-cn.com)>

问题描述

输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可

个人想法

线性扫描加二分查找

时间复杂度:$O(Nlog_2N)$

空间复杂度:$ O(1)$

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Solution {
public int[] twoSum(int[] nums, int target) {
int find = 0;
//线性扫描加二分查找
for(int i=0;i<nums.length;i++){
find = target-nums[i];
int left = 0;
int right = nums.length-1;
int mid = left + (right-left)/2;

while(left<=right){
if(nums[mid] == find){
return new int[]{nums[i],find};
}else if(nums[mid] > find){
right = mid-1;
mid = left + (right-left)/2;
}else{
left = mid + 1;
mid = left + (right-left)/2;
}
}
}
return new int[0];
}
}

官方解法

使用双指针同时从左右两次向中间进行扫描,若当前结果大于target右侧指针向左移动一个单位,若当前结果小于target左侧指针向右移动一个单位,当双指针相遇时跳出,若为扫描到,返回空数组

时间复杂度:$O(N)$

空间复杂度:$ O(1)$

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
class Solution {
public int[] twoSum(int[] nums, int target) {
int i = 0, j = nums.length - 1;
while(i < j) {
int s = nums[i] + nums[j];
if(s < target) i++;
else if(s > target) j--;
else return new int[] { nums[i], nums[j] };
}
return new int[0];
}
}

其他解法

使用哈希表存储扫描过的数据,每遍历一个元素,首先判断$target-nums[i]$是否在hash表中,若在表示有解,直接返回,若不在,将当前的值存储入hash表中

时间复杂度:$O(N)$

空间复杂度:$ O(N)$


本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

本站由 @John Doe 创建,使用 Stellar 作为主题。