• 每日一练leetcode


    两数之和 II - 输入有序数组

    给定一个已按照 升序排列  的整数数组 numbers ,请你从数组中找出两个数满足相加之和等于目标数 target 。

    函数应该以长度为 2 的整数数组的形式返回这两个数的下标值。numbers 的下标 从 1 开始计数 ,所以答案数组应当满足 1 <= answer[0] < answer[1] <= numbers.length 。

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted

    class Solution {
        public int[] twoSum(int[] numbers, int target) {
            if(numbers == null||numbers.length == 0){
                return new int[0];
            }
            int p;
            HashMap<Integer,Integer> map = new HashMap<>();
            for (int i = 0;i<numbers.length; i++){
                int x = numbers[i];
                if(map.containsKey(target-x)){
                    int index = map.get(target - x);
                    if(i > index){
                        p = i;
                        i = index;
                        index = p;
                    }
                    return new int[]{i+1, index+1}; 
                }
                map.put(x,i);
            }
            return new int[0];
    
        }
    } 
    此题和上一题的区别是输出结果要按照1的索引开始,并且是大的在后小得在前,并且是有序的。我们用的HashMap解法:
    执行用时: 2 ms
    内存消耗: 38.7 MB







    正因为是有序的 当然我们会有更有效的方法 来降低时间复杂度和空间复杂度:
    class Solution {
        public int[] twoSum(int[] numbers, int target) {
        int i = 0;
        int j = numbers.length - 1;
        while(i < j){
        int sum = numbers[i] + numbers[j];
        if(target<sum){
            j--;
        }
        else if(target>sum){
            i++;
        }
        else{
            return new int[]{i+1,j+1};
        }
        }
        return new int[]{-1,-1};
        }
    } 
    执行用时: 0 ms
    内存消耗: 38.8 MB

      缩减搜索空间的角度思考这个解法:

      图解双指针解法的原理
    在这道题中,我们要寻找的是符合条件的一对下标 (i, j)(i,j),它们需要满足的约束条件是:

    ii、jj 都是合法的下标,即 0 \le i < n, 0 \le j < n0≤i<n,0≤j<n
    i < ji<j(题目要求)
    而我们希望从中找到满足 A[i] + A[j] == target 的下标 (i, j)(i,j)。以 n = 8n=8 为例,这时候全部的搜索空间是:

    由于 ii、jj 的约束条件的限制,搜索空间是白色的倒三角部分。可以看到,搜索空间的大小是 O(n^2)O(n
    2
    ) 数量级的。如果用暴力解法求解,一次只检查一个单元格,那么时间复杂度一定是 O(n^2)O(n
    2
    )。要想得到 O(n)O(n) 的解法,我们就需要能够一次排除多个单元格。那么我们来看看,本题的双指针解法是如何削减搜索空间的:

    一开始,我们检查右上方单元格 (0, 7)(0,7),即计算 A[0] + A[7] ,与 target 进行比较。如果不相等的话,则要么大于 target,要么小于 target。

    假设此时 A[0] + A[7] 小于 target。这时候,我们应该去找和更大的两个数。由于 A[7] 已经是最大的数了,其他的数跟 A[0] 相加,和只会更小。也就是说 A[0] + A[6] 、A[0] + A[5]、……、A[0] + A[1] 也都小于 target,这些都是不合要求的解,可以一次排除。这相当于 i=0i=0 的情况全部被排除。对应用双指针解法的代码,就是 i++,对应于搜索空间,就是削减了一行的搜索空间,如下图所示。

    排除掉了搜索空间中的一行之后,我们再看剩余的搜索空间,仍然是倒三角形状。我们检查右上方的单元格 (1, 7)(1,7),计算 A[1] + A[7] 与 target 进行比较。

    假设此时 A[0] + A[7] 大于 target。这时候,我们应该去找和更小的两个数。由于 A[1] 已经是当前搜索空间最小的数了,其他的数跟 A[7] 相加的话,和只会更大。也就是说 A[1] + A[7] 、A[2] + A[7]、……、A[6] + A[7] 也都大于 target,这些都是不合要求的解,可以一次排除。这相当于 j=0j=0 的情况全部被排除。对应用双指针解法的代码,就是 j++,对应于搜索空间,就是削减了一列的搜索空间,如下图所示。

    可以看到,无论 A[i] + A[j] 的结果是大了还是小了,我们都可以排除掉一行或者一列的搜索空间。经过 nn 步以后,就能排除所有的搜索空间,检查完所有的可能性。搜索空间的减小过程如下面动图所示:

    作者:nettee
    链接:https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/solution/yi-zhang-tu-gao-su-ni-on-de-shuang-zhi-zhen-jie-fa/
    来源:力扣(LeetCode)

  • 相关阅读:
    正则表达式
    UVALive
    Python科学计算基础篇
    IntelliJ IDEA 2017.3激活与汉化
    hive order by,sort by, distribute by, cluster by作用以及用法
    Hive调优
    Hive 索引
    hive视图
    Hive 分区 分桶使用
    linux内核优化,内核参数详解
  • 原文地址:https://www.cnblogs.com/nenu/p/15028893.html
Copyright © 2020-2023  润新知