算法分析(六):两数之和(有序数组)

74 阅读2分钟

这是我参与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};
    }
}

在这里插入图片描述

总结

  • 这道题目还是相当简单的,可能之前学习的有基础,所以我看一眼就知道需要使用双指针,然后看了题解,没想到还用这么复杂的二分查找法,但是秉着学习的想法一起学习了。