*LeetCode的开端:1. 两数之和(Java & Python)

经典的OJ题,放假了,刷这题作为开始。

题目:

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

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

示例:

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

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

我的解答:

第一个想到的自然是暴力解法:

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

然而看到网上的解答后,才知道是可以用哈希表优化速度,于是又写了一个:

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

其实还可以更快的,将加入hash表和判断放入同一个循环:

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

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

2019.8.21更新

一年了,第二遍刷LeetCode,顺便也复习下原题。这里用Python 3写(还不是为了防止自己偷看以前blog……)

不过一开始还是只能想到O(n^2)解法,但是这次直接给我TLE超时。

我开始思考,这题的核心点是什么?为什么明明写过一遍的题还是不明白?

哪怕我看到了提示:“hash表”这几个字,还是想不出来到底为啥要用hash表?这题和hash表什么关系?

这次在我的实现代码里面,记录下了我所有的思路。

才发现实际上我首先要把这个题变一下形:

这个题不是要去考虑怎么求和,而是要考虑对于每一个数n,怎么在这给定的数组中间找到一个(target-n)的另一个数!

然后哪怕第一次仍然写的是个暴力方法,后期也可以自然地去想到hash表加快查找速度。

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        '''
        leetCode都改的我不认识了呢。
        但是我跟去年刚刷的时候一个感觉啊!完全是脑子一片空白呢
        不过就是再恶心也要先把暴力的解法交出来呢
        Python也不是很熟,先练练手吧。
        据说Python只要一行就能搞定呢。
        第一次提交:WA
        连这种题都能WA的我也是个小白呢,细节错误真的很伤啊
        第二次提交:TLE
        看来O(n^2)的暴力算法在Python这里不行呢。
        又只能偷看题解了呢。
        
        这个地方到底要怎么想呢?
        这里我要换一个思路,
        一开始我想的是找到求和的所有方式,自然就成了O(n^2)
        如果我从另一个角度思考,
        那就是对于每一个数i,都在这个给定的数组去找target - i的另一个数,
        这样才可能想到hash呢(都是套路啊!或许我唯一的办法就是记住这个套路了)。
        我首先就先把这东西弄成一个Hash表吧,因为hash表找东西快呢。
        写Java写习惯了的人表示Python那个类似HashMap的是什么东西?
        对了,字典dict!
        那么接下来就要考虑key和value都是些什么东西了。
        题目要输出的是索引
        应该key是数值,value是索引呢。
        然后因为语法不熟悉,只能疯狂百度用法…
        
        '''
        hash_map = {}
        for index, num in enumerate(nums):
            another_num = target - num
            if another_num in hash_map:
                return [hash_map[another_num], index]
            hash_map[num] = index
        return None;
            
            

 

 

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值