程序程序员首页投稿(暂停使用,暂停投稿)

LeetCode【1】. Two Sum--java的不同方法

2016-08-14  本文已影响1069人  way菜畦

LeetCode,最近才知道有这么好的平台可以刷题,真是惭愧惭愧。现在开始,努力,一道道地刷题!刚开始,难免有不足的地方。也有借用别人思路的部分,学习才能进步!之前想一道道地刷,但是能力问题,又要做其他事,很容易就停下了,今天在豆瓣看到一个对题目进行分类的,挺不错,补充mark一下:LeetCode 题目总结/分类

一、题

第一道题Two Sum 如下:

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

简单来说,就是给一数组及一数值,求数组中两元素相加为该数值对应的两个索引。且要求index1小于index2,而且答案结果稳定。

二、解:

2.1 遍历:

最粗暴的方法,时间复杂度为O(n^2)。一开始提交通不过,太耗时了,后来又可以提交。略奇怪。


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

2.2 HashSet

利用HashSet元素不能重复的原理,新建一个HashSet,然后可先检查target-nums[i]能否加入该HashSet,若能,则说明前面的数据没有与第i个符合的组合。在把该target-nums[i]删除,重新添加nums[i](避免有两个元素相等返回错误判断)。当添加不成功,则说明存在符合的组合,记录此时的i,并从i以前的数组寻找他的另一半。有点繁琐,但时间复杂度为O(n),空间复杂度为O(n)。


public class Solution {  
    public int[] twoSum(int[] nums, int target) {  
        int index1,index2;  
        int[] index=new int[]{0,1};  
        Set nset = new HashSet();  
          
        for(int i = 0; i< nums.length; i++)  
        {  
           if(nset.add(target-nums[i])) //检查是否有nums[i]配对的元素存在,无则添加成功   
           {  
               nset.remove(target-nums[i]); //添加该元素只是为了判断是否存在,本来不应该添加的这里又删掉  
               nset.add(nums[i]);  
           }else  
           {  
               index[1] = i+1;  
               for(int j = 0; j< i; j++)  
               {  
                   if(target==(nums[i]+nums[j]))  
                   {  
                       index[0] = j+1;  
                       return index;  
                   }  
               }  
               return index;  
           }  
             
        }  
        return index;  
    } 
}  

有点奇怪,以上提交后的结果为“Runtime: 332 ms”,但是我把用add()方法来判断是否存在的方式替换成直接用contains()方法来判断,即把“ if(nset.add(target-nums[i])) ”换成“if(!nset.contains(target-nums[i])) ” 然后删掉“nset.remove(target-nums[i]); ”,但是“Runtime: 364 ms”。试了几次,大小有变动,但是总是后者要耗时多点。但实际是少执行一条命令。这里有点疑惑。不知是采用黑盒测试来检验算法的正确性。

另外,有人疑虑HashSet在添加元素的时候去判断是否已存在元素不用去遍历已有的集合吗?这不是跟第一个方法的遍历一样吗?其实不然,HashSet 的元素存放位置是根据每个元素的哈希码来放的,就是知道一个元素,算出其哈希码,就能知道他存放的地址。就像学校,每来一个新生就给他个学号,老师找你不用一间间宿舍去找你,只要知道学号就能直接定位到你的宿舍。

2.3 HashMap

用HashMap来做,道理相同,不过跟二还是有点区别。1、HashMap要需要为每个元素创建key和value两个内存空间,辅助空间翻倍。本例子就是用value来放index;2、由于用value来放index,找到一个后,另外一个就马上可以得到其index。二跟三,一个省点空间、一个省点点时间,都差别不大。


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

参考:LeetCode – Two Sum (Java)

上一篇下一篇

猜你喜欢

热点阅读