• LeetCode-两数之和


    来源:力扣(LeetCode)- 两数之和

    问题

    给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

    你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。

    示例

    给定 nums = [2, 7, 11, 15], target = 9

    因为 nums[0] + nums[1] = 2 + 7 = 9

    所以返回 [0, 1]

    解答

    初步思路

    平时最常用的方法,使用双循环,遍历数组。当内循环的j等于外循环的i时,跳过;当下标为ij的两数之和等于目标值,则保存ij,退出循环。

    class Solution {
        public int[] twoSum(int[] nums, int target) {
            int[] indexs = new int[2];
            for(int i = 0; i < nums.length; i++){
                for(int j = 0; j < nums.length; j++){
                    if(i==j) continue;
                    if(nums[i]+nums[j]==target){
                        indexs[0] = i;
                        indexs[1] = j;
                        i = nums.length;
                        break;
                    }
                }
            }
            return indexs;
        }
    }
    

    缺点:需要循环n*n次,判断n*(n-1)次,耗时,耗内存!

    优化

    因判定条件是 nums[i] + nums[j] == target ,则 i = 1, j = 2i = 2, j = 1的情况相同。故,初步思路中以 j = 0 为内循环初始条件,甚为不妥!如此,将有大约一半的循环是多余的!同时,要满足 j != i ,则可令 j = i + 1 ,既除去了多余的循环,又满足 j != i 。内循环部分代码如下:

    for(int j = 0; j < nums.length; j++){
        if(nums[i]+nums[j]==target){
            indexs[0] = i;
            indexs[1] = j;
            return indexs;
        }
    }
    

    虽然减少了进一半的循环,但是,耗时之间少了一点点,所耗内存,依然很大!

    借鉴

    nums[i] + nums[j] = target ,可得两式:

    • nums[i] = target - nums[j]

    • target - nums[i] = nums[j]

    可使用单循环,保存等式左边,寻找等式右边,由此,则将等号单侧的两个变量变为一个,妙哉!

    • 保存 target - nums[i] 寻找 nums[j] :
    int[] indexs = new int[2];
    HashMap<Integer,Integer> hash = new HashMap<Integer,Integer>();
    for(int i = 0; i < nums.length; i++){
        if(hash.containsKey(nums[i])){
            indexs[0] = hash.get(nums[i]);
            indexs[1] = i;
            break;
        }
        hash.put(target-nums[i],i);
    }
    return indexs;
    
    • 保存 nums[i] 寻找 target - nums[j] :
    int[] indexs = new int[2];
    HashMap<Integer,Integer> hash = new HashMap<Integer,Integer>();
    for(int i = 0; i < nums.length; i++){
        if(hash.containsKey(target - nums[i])){
            indexs[0] = hash.get(nums[i]);
            indexs[1] = i;
            break;
        }
        hash.put(nums[i],i);
    }
    return indexs;
    

    显然,这次只循环了n次,耗时大幅减少,但是,内存的消耗,似乎并没有减少!

  • 相关阅读:
    报错:无法截断表 '某表',因为该表正由 FOREIGN KEY 约束引用
    如何选择使用结构或类
    C#交换两个变量值的多种写法
    什么是.Net, IL, CLI, BCL, FCL, CTS, CLS, CLR, JIT
    把数据库中有关枚举项值的数字字符串转换成文字字符串
    为参数类型一样返回类型不同的接口写一个泛型方法
    报错:System.NotSupportedException: LINQ to Entities does not recognize the method
    关于泛型类和扩展方法的一点思考
    在ASP.NET MVC下通过短信验证码注册
    ASP.NET MVC下实现前端视图页的Session
  • 原文地址:https://www.cnblogs.com/HenuAJY/p/13132536.html
Copyright © 2020-2023  润新知