这是我参与11月更文挑战的第6天,活动详情查看:2021最后一次更文挑战
前言
- 这道题主要考察的是二分查找和双指针的算法,因为从有序的数组中找到一个数的两个因子就是搜索问题,一般这种问题都是用这两种方法比较好
- 题目地址:leetcode-cn.com/problems/tw…
第一种解法:二分查找
- 这一个解法我觉得太麻烦,并且双指针明显更好,但是学习不是只为了解决问题,多学一点也是为了以后碰到不一样的问题有更好的想法。
- 第一步我先假设第一是因子,然后让第一个到最后一个这个区间作为因子去查找
- 第二步查找答案,这个时候就需要使用二分查找,通过确定中间数与结果相对比的大小来进行缩小范围,最后找到答案
- 话不多说直接上代码:
class Solution {
public int[] twoSum(int[] numbers, int target) {
for (int i = 0; i < numbers.length; ++i) {
int low = i + 1, high = numbers.length - 1;
while (low <= high) {
int mid = (high - low) / 2 + low;
if (numbers[mid] == target - numbers[i]) {
return new int[]{i + 1, mid + 1};
} else if (numbers[mid] > target - numbers[i]) {
high = mid - 1;
} else {
low = mid + 1;
}
}
}
return new int[]{-1, -1};
}
}
第二种解法:双指针
-
因为是有序数组,所以我们直接创建两个指针,一个指向有序数组的最小值也就是最左端,一个指向有序数组的最大值也就是最右端
-
第一步,将两数相加和目标数进行判断
-
第二步,如果等于目标数就直接输出,如果大于目标数,就让最大数像左移也就是变小,如果小于目标数,就让最小数向右移动也就是变大
-
第三步,一直循环,最后如果没有返回就是没有找到,返回一个空
-
代码如下:
class Solution {
public int[] twoSum(int[] numbers, int target) {
int left = 0;
int right = numbers.length -1;
while(left <= right){
if(numbers[left] + numbers[right] == target){
return new int[]{left+1,right+1};
}else if(numbers[left] + numbers[right] < target){
left++;
}else{
right--;
}
}
return new int[]{-1, -1};
}
}
总结
- 这道题目还是相当简单的,可能之前学习的有基础,所以我看一眼就知道需要使用双指针,然后看了题解,没想到还用这么复杂的二分查找法,但是秉着学习的想法一起学习了。