根据题目描述:给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
这样大多数人的思路都很明确,就是从头遍历数组找到两个数和目标数相同则返回下标。
核心代码如下:
for (int i =0;i
这样确实可以得到结果,但是用时较长,在数组较大时,速度较慢。也就是时间复杂度很高O(n^2),一般在我们的程序中,时间复杂度不能为指数递增。这个方法虽然方便,大多数人都能想到,但是程序不是最优。
程序执行结果:
提交程序用时
在第一种方法的基础上,我们不能允许程序中有指数递增的时间复杂度存在,我们得进行优化。怎么优化呢?我们想到java中有Map接口,Map接口中键和值一一映射. 可以通过键来获取值。给定一个键和一个值,你可以将该值存储在一个Map对象. 之后,你可以通过键来访问对应的值。
我们可以将数组中的元素和下标存储到map中,因为map键值对映射的时间复杂度为O(1),这样的话就大大增加了程序的执行速度。
核心代码如下
Map map = new HashMap ();
for (int i=0;ii){
System.out.println("序号为:["+i+","+map.get ( shuzhi )+"]");
}
}
这样得到的结果用的时间比第一种大大减少,时间复杂度为O(n).这样就对第一种方法进行了优化。提高了效率。
程序执行结果:
提交程序用时
有人可能会想,第二种方法已经很快了,还有比这个更快的方法吗,当然。
观察第二种方法我们不难发现,他将数组元素存储map和与目标元素的具体比较分别进行了处理。我们是不是可以这样想,将他们放到一起,在一个for中进行处理,这样就减少了一个步骤。速度能比第二种方法较快一点。时间复杂度与第二种相同都是O(n).
核心代码如下
for (int i=0;i
代码量相比第二种减少了一些,效率也更高。这个代码将找找两个数的和等于目标数的操作和数组元素存储到map中的操作放到了一起,先进行判断,再进行存储。
程序执行结果:
提交程序用时
第四种方法用时介于第一中和第二种方法之间,时间复杂度是log级别的。
具体思路就是:首先得进行排序(排序方法有好多,冒泡,快速,选择,或者用java自带的排序函数),然后标记排好序数组元素的首位置和末位置,将两者对应元素相加与目标数进行比较,大于目标数则将末尾值向前移动,小于目标数首位置向后移动,直到找到等于目标数的两个元素停止,输出下标。
需要一个存储下标的容器,我选择map。但是map中的key是不能重复的,所以,我们可以想到,让一个key拥有多个value。例如[3,3]数组,存储到map中就是,key:3,value:[0,1]。这样就可以解决遇到数组中重复元素时,map键不能重复的问题。
核心代码如下
int a=0;
int b=num.length-1;
Map> map = new HashMap();
for (int i = 0; i < num.length; i++) {
//当不存在键时,正常插入
if (!map.containsKey ( num[i] )){
List list1 = new ArrayList <> ( );
list1.add ( i );
map.put ( num[i],list1 ); // 将值和下标存入Map
}
else {
//当存在键时,将键对应的值添加道列表里,这样就形成了一个键对应多个值
List list2 = map.get ( num[i]);
list2.add ( i );
map.put ( num[i],list2 );
}
}
System.out.println(map);
Arrays.sort (num);//用自带的排序函数
for (int i=0;itarget){
b=b-1;
}
else if((num[a]+num[b])<><>"+map.get (num[b]));
}else if(a!=b){
System.out.println("序号为:"+map.get (num[a]));
}
a=a+1;
}
}
程序执行结果:
这个结果测试了极端问题,数组中有重复元素时,map一个键
对应多个值,可以实现。其他的测试数据也与前三种相同。时间复杂度O(nlogn)级别。
leetcode第一题,两数之和,看似不难,但背后需要考虑很多问题。时间与空间转换问题,数组极端值问题等等。通过这一道题我收获很多,明白了考虑问题得全面。这是本人第一次写博客,本人是一名真正的小白,在此感谢陈学长给我的循循善诱,一步一步的让我明白一个问题应该从哪个角度考虑。本博客由于本人能力有限,肯定有很多的问题,再此大家谅解。
2019-1-15记录