leetcod刷题---两数之和

吐槽

今天好冷哇哇哇,真的是冻死人了,今天看猫猫老睡在那里,然后我过去就舔我的手和脸emmmm。

题目

两数之和给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。

你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。

示例:

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

因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

思路

这道题还是那种看起来很简单很简单的题目
是个人都能想到两层循环什么的,直接求出来
比如我写的第一版的代码

public int[] twoSum(int[] nums, int target) {
    if (nums.length < 2){
        return null;
    }
    int [] result = 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){
                result[0] = i;
                result[1] = j;
                break;
            }
        }
    }
    return result;

}

时间大概就是跑完样例50ms 尴尬了

所以说,以后遇到这种简单的题目的话,两层循环什么的肯定先要最后考虑,实在不行再考虑用两层循环

这道题就是简单的在数组中找到两个数子加起来就可以等于目标值
如何减少一层循环呢
用Map
//java的方便之处,感觉有点取巧了

思路也很简单

  • 把数值作为 key,它的下标作为 value
  • 遍历数组,判断 map 是否含有这个目标值-当前数值,
  • 有直接返回,没有的话放到map里面

代码如下,测试用例的时间是5ms

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

然后我好奇看了下这道题2ms的解答算法,简直是自己完全看不懂啊啊啊啊,好像和我都是用的是java啊,,,很尴尬唉

  public int[] twoSum(int[] nums, int target) {
        final int il = nums.length;
        int il2 = (il >> 2) - 1;

        int pot = 2;
        while((il2 >>= 1) > 0) pot <<= 1;
        final int bitMod = pot - 1;
        final int[] bucket = new int[pot];
        final int[] linked = new int[il];

        final int firstVal = nums[0];

        for (int i = 1; i < il; i++) {
            int currNum = nums[i];
            int complement = target - currNum;

            if (complement == firstVal) {
                return new int[] { 0, i };
            }

            int complementLLIndex = bucket[complement & bitMod];
            while(complementLLIndex != 0) {
                if(nums[complementLLIndex] == complement) {
                    //Found
                    return new int[] { complementLLIndex, i };
                }
                complementLLIndex = linked[complementLLIndex];
            }
            int currNumLLIndex = currNum & bitMod;
            linked[i] = bucket[currNumLLIndex];
            bucket[currNumLLIndex] = i;
        }
        return null; 
    }

总结

  • 刷题时候一般避免用多重循环什么的
  • 如果非要用的话,可以用map代替一层循环//java刷题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值