哈希
1.两数之和:
给定一个整数数组nums 和一个整数目标值target ,请你再该数组中找出和为目标值target 的那两个整数,并返回它们的数组下标。
思路 :暴力解法是使用两层循环来遍历每一个数,然后找出两数之和等于target的数,但是这样时间复杂度就是O(n^2)。为了减少时间复杂度,我们可以考虑用空间换时间,考虑使用HashMap。HashMap内部是使用数组来存储数据的,因此他提供O(1)查找效率。我们再遍历数组的时候,同时将元素插入到HashMap中,然后我们检查target减去当前元素后的值再HashMap中是否存在,存在的话说明找到了两个数组元素相加等于target,将这两个元素用一个新的数组保存起来作为最终返回的答案即可。这样做我们只需要遍历一次数组就可以找到结果把时间复杂度降低到O(n)。
java
import java.util.*;
import java.io.*;
public class Main{
public static void main(String args[]){
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int target = in.nextInt();
int[] nums = new int[n];
for(int i=0;i<n;i++){
nums[i] = in.nextInt();
}
Map<Integer,Integer> map = new HashMap<>();
int[] res = new int[2];
for(int i=0;i<n;i++){
int num = target - nums[i];
if(map.containsKey(num)){
res[0] = i;
res[1] = map.get(num);
}
map.put(nums[i],i);
}
System.out.println(Arrays.toString(res));
// 对于二维数组或多维数组可以使用Arrays.deepToString()
// System.out.println(Arrays.deepToString(res));
}
}
2.字母异位词分组
给你一个字符串数组,请你将字母异位词 组合在一起。可以按任意顺序返回结果列表。字母异位词是由重新排列源单词的所有字母得到的一个新单词。
思路 :因为是字母异位词,因为把他们提取出来做个排序,得到的字符串肯定是相等的,因此我们可以利用HashMap的key-value的数据结构,把排序后的字符串作为key,这样遍历到数组中的字符串时,先做个排序,然后查询下HashMap中是否有该字符串,没有的话就创建一个然后加入进去,有的话就直接加入到该key的value中,因为value里面可能存放不止一个字符串,因此构建HashMap的时候valu的结构需要是List<String>,这样遍历一遍之后就一键分类完成了。
java
import java.util.*;
import java.io.*;
public class Main {
public static void main(String args[]) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
in.nextLine(); // 消费掉nextInt后的换行符
if(n == 0) {
System.out.println(new ArrayList<>());
return;
}
String[] strs = new String[n];
for (int i = 0; i < n; i++) {
strs[i] = in.nextLine();
}
Map<String, List<String>> map = new HashMap<>();
for (String s : strs) {
char[] c = s.toCharArray();
Arrays.sort(c);
String sorted = new String(c);
// if(!map.containsKey(sorted)){
// map.put(sorted,new ArrayList<>());
// }
map.putIfAbsent(sorted, new ArrayList<>()); // 更简洁的方式来处理不存在的键
map.get(sorted).add(s); // 正确的方法是add
}
// 直接打印map的values即可,它会自动调用toString()方法
System.out.println(new ArrayList<>(map.values()));
}
}
3.最长连续序列
给定一个未排序的整数数组nums ,找出数字连续的最长序列(不要求序列元素在元数组中连续)的长度。请设计并实现时间复杂度为O(n)的算法解决此问题。
思路 :我们可以思考一种办法,就是遍历每一个数,然后以该数为起点,通过+1的方式继续寻找下一个连续的数,然后记录最大的连续长度,因为HashSet(没必要使用HashMap,键值对在这题用不上,只需要存储唯一的元素集合即可)可以提供O(1)查找时间复杂度,因此我们可以考虑先把数组里面的元素放入到HashSet中,然后再遍历数组中的每一个元素,如果改元素在数组里没有连续的前缀元素,说明可以以该元素作为起点开始查找连续序列,然后设置计数器,遍历完之后比较以该元素作为起点的连续序列长度是否是最长。
java
import java.io.*;
import java.util.*;
public class Main{
public static void main(String args[]){
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] nums = new int[n];
for(int i=0;i<n;i++) nums[i] = in.nextInt();
Set<Integer> set = new HashSet<>();
for(int i=0;i<n;i++) set.add(nums[i]);
int res = 0;
for(int i=0;i<n;i++){
if(!set.contains(nums[i] - 1)){
int num = nums[i] + 1;
int count = 1;
while(set.contains(num)){
count++;
num++;
}
res = Math.max(res,count);
}
}
System.out.println(res);
}
}
持续刷题中...