问题描述
首先自己拿到题目还是想到
暴力解法
就是用两个for循环的方式,进行n*n遍历,如果两数结果相加等于target就返回
int last = 0; //用来记录target减去第一个数字后的剩余值 比如6-2,剩余的4就是last
for(int i = 0;i < nums.length;i++){
last = target-nums[i]; //进行第一次减法,留下last,然后用last在另一层循环中进行匹配.
for(int j = 0;j < nums.length;j++){
if(last - nums[j] == 0 && i != j){ //如果匹配到了last,并且没有重复运用元素就返回.
return new int[]{i,j};
}
}
}
return null;
这样显然是最低效的,接着看别人的代码
在这个问题中,用HashMap进行存储,key为元素,value为它的下标.
因为HashMap中查找key只需要o(n).
首先用target减去第一个数字,看剩余数字是否在hashmap中,如果存在直接返回value和i.
如果不存在,将其存入HashMap.
HashMap hashMap = new HashMap( nums.length );
int last = 0;
for (int i = 0; i < nums.length; i++) {
last = target - nums[i];
if(hashMap.containsKey( last)){
return new int[]{( int ) hashMap.get( last ),i};
}else{
hashMap.put( nums[i],i );
}
}
return null;
接着看最后一位的代码,排名第一的代码.
采用一个数组模仿hashmap的存储结构.数组的下标是nums[]中元素和2047(1111111111)相与的结果,数组的值初始都是0.
如果要存入的话值是nums中元素下标+1
在执行时还是先计算last = target-nums[i];然后通过与进行查找,不存在就将nums[i]对应下标+1放入数组中,如果存在就返回结果.
int indexArrayMax = 2047;
int[] indexArrays = new int[indexArrayMax+1];
int last = 0;
for (int i = 0; i < nums.length ; i++) {
last = target - nums[i];
if(indexArrays[last & indexArrayMax] != 0){
return new int[]{indexArrays[last & indexArrayMax]-1,i};
}else{
indexArrays[nums[i] & indexArrayMax] = i+1;
}
}
throw new IllegalArgumentException( "no two sum value" );