两数之和–力扣
这是第一次在力扣上面刷题,先做了一个简单的,但还是有很多的问题,下面就来写一写做题经过和学习心得,这里主要用Java。
题目
思路
首先,暴力的解法就是使用双层for循环,时间复杂度为O(n^2),我考虑了暴力解法,之前主要使用C语言多,所以虽写出来了,但是效率很低。
这个题呢,要用map,首先先来回忆一下Java中有关map的相关知识。
在Java中,Map接口:
- Map中的元素都是成对出现的,以键值对映射的形式存储和管理数据
- 每个对象都有一个唯一的key值,每个key对应一个value ,通过key可以实现对value对象的访问
- key和value都为Object对象
- Key对象唯一不重复,value对象允许重复
- Map接口常用实现类:HashMap,Hashtable
这里重点要用到HashMap ,该实现类的相关性质:
- Map的实现类,与HashSet类似,底层也采用哈希散列算法管理映射, 通过key的哈希码进行散列运算,计算出与之对应的value在内存中的位置
- HashMap中存储的映射无顺序
- 允许存储null键和null值
- 这里用到的方法:boolean containsKey(Object key)
是判断是否包含指定的键值
返回值:如果Map集合中包含指定的键名,则返回true;
否则返回false。
主要的思路是:
用一个for循环遍历数组中所有的元素,以传过来的数减去数组元素为key值,下标大小为value值封装为HashMap集合,判断每个数组元素是否包含指定的键值,如果包含,则该数组的下标还有该键值就是所求的,将这两个封装在一个数组中返回出来即可。
代码
暴力方法:
class Solution {
public int[] twoSum(int[] nums, int target) {
if(nums.length==0 || nums.length==1){
return new int[0];
}
int sum = 0;
int[] s = new int[2];
for(int i=0;i < nums.length-1;i++) {
for(int j= i + 1;j < nums.length; j++) {
sum = nums[i]+nums[j];
if(sum == target) {
s[0] = i;
s[1] = j;
}
}
}
return s;
}
}
使用map后:
class Solution {
public int[] twoSum(int[] nums, int target) {
if(nums==null || nums.length==0 || nums.length==1 || nums.length==2) {
return new int[0];
}
int[] s = new int[2];
Map<Integer,Integer> map = new HashMap<>();
for(int i = 0; i < nums.length; i++){
int temp = target - nums[i];
if(map.containsKey(temp)){
s[0] = i;
s[1] = map.get(temp);
}
map.put(nums[i],i);
}
return s;
}
}
改进后:
class Solution {
public int[] twoSum(int[] nums, int target) {
if(nums==null || nums.length==0 || nums.length==1 || nums.length==2) {
return new int[0];
}
int[] s = new int[2];
Map<Integer,Integer> map = new HashMap<>();
for(int i = 0; i < nums.length; i++){
if(map.containsKey(nums[i])){
s[0] = i;
s[1] = map.get(nums[i]);
return s;
}
map.put(target-nums[i],i);
}
return new int[0];
}
}
总结:一开始的空间、时间复杂度都考虑的太少了,导致了一些浪费,以后的练习中要多多思考,不断地改进,总算结果没那么的强差人意。