开始LeetCode刷题的第一天

重回代码之我是谁

  很久没打代码了,重新回到LeetCode练练手,然后满心充斥着几个问题:我是谁?我在哪?我要干什么?
  不知道各位是否有这种感觉,很久不熟练代码之后,尽管你的思路还挺清晰,但是你会发现遗忘了很多基础问题,比如说各种集合…所以说现在开端想给我自己同时也给大家一个告诫:“不可一日不打代码”AND“开发大道就像逆水行舟,不进则退”

重生LeetCode之第一题也能关我?

  在重新做第一题之前,我是没想到曾经秒秒钟解决的我会卡了这么久…各种基础知识的遗忘以及错误的操作规范,让我在这卡的怀疑人生…以下是这道题的相关内容:

  给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那两个整数,并返回它们的数组下标。
  你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
  你可以按任意顺序返回答案。
  示例 1:
  输入:nums = [2,7,11,15], target = 9
  输出:[0,1]
  示例 2:
  输入:nums = [3,2,4], target = 6
  输出:[1,2]
  示例 3:
  输入:nums = [3,3], target = 6
  输出:[0,1]

  这道题我看到的第一时间想到的是用一个循环(不知道怎么回事脑抽了),然后在循环里对 i 进行+1,结果发现效率奇低(能不能实现不确定,我弄到一半就换成双循环了)。然后很尴尬的事情发生在了写双循环的过程中。

双循环中发现自己就是个弱鸡

  在最开始写双循环的过程中,我甚至忘记了基本规则——变量的适用范围。这里就不详细说明了,基本上刚开始学过的都多少遇到过这种问题。(说的自己跟个萌新一样…私密马赛…)在经过了长达半个多小时的艰难编程之后,第一版终于写出来了。

class Solution {   
    public static int[] twoSum(int[] nums, int target) {
        int start;
        int first;
        int second;
        int result;
        int[] results = new int[2];
        for(start=0;start<nums.length;start++){
            //从前往后遍历,每个start都是first
            first = nums[start];// 数组中依次的第一个数
            second = target - first;//不同的第一个数相对应的第二个数
           for(int i = 1; start + i < nums.length ; i++ ){
               if(nums[start + i] == second){
                   results[0] = start ;
                   results[1] = start + i;
               }
           }
        }
        return results;
    }
}

  可能很多萌新第一眼还看不出什么问题,但对比一下下一版就知道了。

class Solution {   
    public static int[] twoSum(int[] nums, int target) {
        int start;
        int first;
        int second;
        int result;
        int[] results = new int[2];
        for(int i =0 ; i<nums.length;++i){
           for(int j = i + 1; j  < nums.length ; ++j ){
               if(nums[i] + nums[j] == target){
                   results[0] = i ;
                   results[1] = j;
               }
           }
        }
        return results;
    }
}

  可以很明显的看出少了很多多余的赋值。可能在这种小的实现中看不出什么大的差异,但是业务繁重以后这些都是可以优化的点。然后在看了别人的回答以后,进一步优化出了第三版,也就是双循环的最终版。

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

  这个是不是更明显了…比之前少了很多变量,然后对于数组的赋值也是直接在创建的时候加入了进去,效果不好说,但是从整个代码的整洁度和可读性方面来说,有了很大的提升。但是这三种改进其实没有根本性的优化,我觉得更多的来说还是增加了整洁性和可读性,效率没有什么变化。如下图:
前三次的效率比较

看答案解析发现的意料之外情理之中的答案

  话不多说,先上代码:

class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> hash = new HashMap<Integer, Integer>();
        for (int i = 0; i < nums.length; ++i) {
            if (hash.containsKey(target - nums[i])) {
                return new int[]{hash.get(target - nums[i]), i};
            }
            hash.put(nums[i], i);
        }
        return new int[0];
    }
}

  好家伙,看完才恍然大悟————Bee————Map的K-V键值对居然被我遗忘了…只能说上Map之后这代码看起来才有了些味道。(简洁流畅效率高的代码才是我们的毕生追求!)每一个K值 i 遍历寻找他对应的V值 target - nums[i],如果找到了返回True,否则返回False。ContainsKey:如果 hashMap 中存在指定的 key 对应的映射关系返回 true,否则返回 false。最后根据结果,用get获取键k的值,即对应的序号。同时为了防止与自己匹配, 将遍历过的值put到Hashmap中。以下,是对应的效率:
最后一次的效率
  只能说,这就是差距吧…

总结

  总之这次重刷题发现很多东西掌握的确实不牢固,还有待加强,多努力,多记,多刷题,争取早日变成大牛!题海战术在某方面来说可是相当有用的,干巴爹!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值