题目
日常第一步,先把题目贴过来
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
看不懂的兄弟们自己手动找度娘翻译,笔者亲身体验,相当准。
思路
这道题说白了就是让给一堆数,找到两个加起来等于给定值的数据,返回他们的索引。
需要注意的就是,同一个数据不能用两次,别的也没啥。直接循环,简单粗暴加无脑,本人最爱。
代码
public class Two_Sum {
public static void main(String[] args) {
int target = 9;
int[] nums= {2, 7, 11, 15};
System.out.print( twoSum( nums, target )[0] + " " + twoSum( nums, target )[1] );
}
public static int[] twoSum(int[] nums, int target) {
int[] output = 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 ) {
output[ 0 ] = i;
output[ 1 ] = j;
return output;
}
}
}
return output;
}
}
总结
看了大佬们的题解之后发现,可以采用哈希表的方法,一遍查询一边插入,最后时间复杂度为O(n)。
先查询,是否存在和当前值和为target的值,存在就返回他的下表,存储后返回结果;不存在就将其插入哈希表中,继续往下循环。
其中,哈希表的结构为:
Key | Value |
---|---|
nums[i] | i |
另外关于new HashMap<Integer,Integer>()和new HashMap<>()的区别:
初始化方法 | 执行用时 | 内存消耗 |
---|---|---|
new HashMap<Integer,Integer>() | 8 ms | 39.4 MB |
new HashMap<>() | 3 ms | 37.3 MB |
明显能够看出来,不管是时间还是空间,都是new HashMap<>()更优,大致查了一下资料,发现new HashMap<Integer,Integer>()和new HashMap<>()没有太大的区别(底层函数相同),如果说是有的话就是带有泛型的在输出的时候无需向下转化,直接进行输出,而不带泛型的需要从Object类型向下转化后才进行输出。
最后我在电脑上用以下代码进行了一个测试,最后的结果很尴尬,不管是输入还是输出,带有泛型的都比不带泛型的时间少。所以,,,,真尴尬
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] nums= {2, 7, 2, 15};
HashMap<Integer, Integer> input1 = new HashMap<>();
HashMap<Integer, Integer> input2 = new HashMap<Integer, Integer>();
double T1 = System.nanoTime();
for( int i = 0; i < nums.length; i++ )
input1.put(i, nums[i]);
double T2 = System.nanoTime();
for( int i = 0; i < nums.length; i++ )
input2.put(i, nums[i]);
double T3= System.nanoTime();
for( int i = 0; i < nums.length; i++ )
input1.get(i);
double T4= System.nanoTime();
for( int i = 0; i < nums.length; i++ )
input2.get(i);
double T5= System.nanoTime();
System.out.println( "不带有泛型的输入时间:"+ (T2-T1) );
System.out.println( "带有泛型的输入时间:"+ (T3-T2) );
System.out.println( "不带有泛型的输出时间:"+ (T4-T3) );
System.out.println( "带有泛型的输出时间:"+ (T5-T4) );
}
优化过的代码
public int[] twoSum(int[] nums, int target) {
int[] output = new int[2];
//这样更快
HashMap<Integer, Integer> input = new HashMap<>();
//HashMap<Integer, Integer> input = new HashMap<Integer, Integer>();
for( int i = 0; i < nums.length; i++ ) {
output[1] = i;
if( input.containsKey(target-nums[i]) ) {
output[0] = input.get(target-nums[i]);
return output;
}else
input.put( nums[i], i);
}
return null;
}