一、两数之和:
(1) 题目要求:
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
示例 1:
输入: | nums = [2,7,11,15], target = 9 |
输出: | [0,1] |
解释: | 因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。 |
(2) 解题思路:
①暴力枚举法:
/**
方法一、暴力枚举
思路算法:
枚举数组中的每一个数x,寻找数组中是否存在target-x。
只需要在x后面的元素中寻找。
复杂度分析:
时间复杂度:O(n2),其中n使数组中的元素的数量。最坏情况下数组中任意两个数都要被匹配一次。
空间复杂度: O(1)
*/
class Solution{
public int[] twoSum(int[] nums,int target){
int len=nums.length;
for(int i=0;i<len;++i){
for(int j=i+1;j<len;++j){
if(nums[i]+nums[j]==target){
return new int[]{i,j};
}
}
}
return new int[0];
}
}
②哈希表法
标签:哈希映射
这道题本身如果通过暴力遍历的话也是很容易解决的,时间复杂度在 O(n2)。由于哈希查找的时间复杂度为 O(1),所以可以利用哈希容器 map 降低时间复杂度。遍历数组 nums,i 为当前下标,每个值都判断map中是否存在 target-nums[i] 的 key 值。如果存在则找到了两个值,如果不存在则将当前的 (nums[i],i) 存入 map 中,继续遍历直到找到为止,如果最终都没有结果则抛出异常。
时间复杂度:O(1)
//map(key-value)
import java.util.Map;
import java.util.HashMap;
public class Solution{
public int[] twoSum(int[] nums,int target){
int len=nums.length;//3
Map<Integer,Integer> hashMap =new HashMap<>(len-1);
hashMap.put(nums[0],0);//{(2-0)...}
for(int i=1;i<len;i++){//① 1 ②2
int another=target-nums[i];//①11 ②2
if(hashMap.containsKey(another)){//①false ②true
return new int[]{hashMap.get(another),i};//[0,2]map.get()获取key为another对应的value值
//有就直接输出数组
}
//没有就存入哈希表,再从哈希表中查找是否存在相应的key值hashMap.containsKey(another)
hashMap.put(nums[i],i);// map.put(key,value) 存入{(2-0),(7-1)}
}
throw new IllegalArgumentException("No two sum solution");
}
}
图片画解:
作者:guanpengchn 链接:https://leetcode-cn.com/problems/two-sum/solution/jie-suan-fa-1-liang-shu-zhi-he-by-guanpengchn/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
(3)题解中涉及到的知识:
集合框架:
- Collection
- Map:双列数据,存储key-value对的数据 —类似于高中的函数y=f(x)
-
HashMap:作为Map的主要实现类:线程不安全的,效率高;可以存储null的key和value
LinkedHashMap:保证在遍历map元素时,可以按照添加的顺序实现遍历。
原因:在原有的HashMap底层结构的基础上,添加了一对指针,指向前一个和后一个元素:
对于频繁的遍历操作,此类执行效率高于HashMap。 -
TreeMap:保证按照添加的key-value对进行排序,实现排列遍历。此时考虑key的自然排序和定制排序。底层使用的是红黑树
-
Hashtable:作为Map的老实现类:线程安全,效率低;不可以存储null的key和value
Properties:常用来处理配置文件。key和value都是String类型 -
HashMap的底层:数组+链表(jdk7之前)
数组+链表+红黑树(jdk8) -
Map结构的理解
Map中的key:无序的、不可重复的,使用Set存储所有的key —key所在的类要重写equals()和hashCode()(以HashMap为例)
Map中的value:无序的、可重复的,使用Collection存储所有的value —value所在的类要重写equals()
一个键值对:key-value构成了一个Entry对 象。
Map中的Entry:无序的、不可重复的:使用Set存储所有的entry
Map中定义的方法:
-
添加、删除、修改操作:
- Object put(Object key,Object value):将指定key-value添加到(或修改)当前map对象中
- Void putAll(Map m):将m中所有key-value对存放到当前map中
- Object remove(Object key):移除指定key的key-value对,并返回value
- Void clear(0:清空当前map中的所有数据
-
元素查询的操作:
- Object get(Object key):获取指定key对应的value
- boolean containsKey(Object key):是否包含指定的key
- boolean containsValue(Object value):是否包含指定的value
- int size():返回map中key-value对的个数
- boolean isEmpty():判断当前map是否为空
- boolean equals(Object obj):判断当前map和参数对象obj是否相等
-
元视图操作的方法:
- Set keySet():返回所有key构成的Set集合
- Collection values():返回所有value构成的Collection集合
- Set entrySet():返回所有key-value对构成的Set集合。