LeetCode(1): Two Sum

【题目】Two Sum

【描述】

Given an array of integers, find two numbers such that they add up to a specific target number.

The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.

You may assume that each input would have exactly one solution.

Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2

【中文描述】给一个Integer数组,要求找到两个数,其和刚好为给定的target数。返回一个数组,里面需包含这两个数的位置,实际就是其数组下标+1。题目还明确,可以认为给的每一个数组都有唯一解。

———————————————————————————————————————————————————————————————————————

【初始思路】

基本上没有算法基础的人,也能立马给一个brute解法,先扫一遍数组,对每个数x,在剩下数组里找target-x。找到即加数组,然后返回。由于题目写明有且有唯一解,所以不需要考虑其他情况。

然后迅速撸了一个,显然,按照上面分析,两个循环嵌套,O(n2)的解法leetcode是绝对不会接受的。所以直接给我Time Limitation Exceeds了,那就想想有没有O(logN)解法,甚至是O(N)解法吧。

【灵光一现!】

扫数组是肯定的,问题在于找 target-x 的过程能不能快速找到。由于题目要求返回两个数各自的位置,这就说明绝对无法(简单办法下)给数组排序然后二分查找解决。那怎么办呢?

这个时候,应当立马想到,有什么东西查找时间复杂度是O(1)的呢?答案也是显然的,需要借助特殊的数据结构,在java里,那就是HashMap了(HashMap是HashTable的进化版,线程不安全,但是功能更强大,这样简单的场合非常适用,查找时间复杂度为O(1))。

【重整思路】

(1) 先扫数组,然后把每个数的位置用map记录下来,使用K-V对:<a[i] , i>。

(2) 然后扫数组,对每个数a[i],在map中找get(target-a[i]),如果找到,两个位置存入数组,直接返回。

这个方法很简单,又速度撸了一个,提交,结果居然又Time Limitaion Exceeds了。简直懊恼!无奈,继续想时间都去哪了。

 

【重整思路,again】

第一次扫数组建map的过程显然很耗时间,这是一个O(n)操作。后面再扫一次,实际上总体是个2N的时间。

能不能在第一次建map的时候直接就找了呢?两次合为一次,答案是肯定的。思路来了:

在扫数组的时候:

     对于每个数a[i],直接计算其对应的target - a[i]为何,然后在map里先找一次。找到直接return;找不到没关系,a[i]加入map,continue。

由于题目说的很清楚,有且必有一个解。所以找不到不用怕,总会找到。这是关键,这一点想明白了,题目很简单!

  

【Show me the Code!!!】

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

 

这个题,其实想明白一次扫数组同时干两个事情,就很简单。想不明白,就始终AC不了。所以这就是它medium的原因吧。

 

【总结一下】

在需要O(1)时间找到某个元素的时候,有几个选择:

1、数组可以按照下标找数;

2、在不知道下标的时候要求在一堆数中找某个具体值,优先考虑HashMap!

posted @ 2015-09-05 09:24  RockIt  阅读(152)  评论(0编辑  收藏  举报