两数之和
输入
nums = [3,3],target = 6
输出
[0,1]
输入
nums = [3],target = 6
输出
[]
暴力解法
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] arr = new int[2];
for(int i = 0;i < nums.length;i++){
for (int j = 0;j < nums.length;j++){
int sum = nums[i]+nums[j];
if(sum == target && i != j){
arr = new int[]{i,j};
}
}
}
return arr;
}
}
哈希优化
每一次遍历都放入HashMap里
等第二个符合条件的就可以直接在hashMap找到了
先判断在放入,避免是相同的
class Solution {
public int[] twoSum(int[] nums, int target) {
HashMap<Integer,Integer> hashMap = new HashMap<>();
//这种写法是在遍历到符合条件的第二个数时才返回
for(int i = 0;i < nums.length;i++){
int key = target - nums[i];
//进行判断是否含有key
if(hashMap.containsKey(key)){
return new int[]{i,hashMap.get(key)};
}
//判断完再put,这样可以保证不会使用自身
hashMap.put(nums[i],i);
}
return new int[0];
}
//新建了一个hashMap,空间复杂度为O(n)
//一个for循环遍历数组,时间复杂度为O(n)
}
字母异位词分组
字符串排序
map转list
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
HashMap<String,List<String>> hashMap = new HashMap<>();
for(String str:strs){
//排序得到key
char[] chars = str.toCharArray();
Arrays.sort(chars);
String key = Arrays.toString(chars);
//放入map中
List<String> list = hashMap.getOrDefault(key, new LinkedList<>());
list.add(str);
hashMap.put(key,list);
}
//map转list
return new LinkedList<List<String>>(hashMap.values());
}
}
最长连续序列
这个比较简单,有思路就行,实现不难
以题解中的序列举例:
[100,4,200,1,3,4,2]
去重后的哈希序列为:
[100,4,200,1,3,2]
我们的目的是找出最前面的那个,所有4,3,2都是可以跳过的
只对1,100,200进行
第二次遍历记得是对hashset进行遍历,如果对nums会超时
class Solution {
public int longestConsecutive(int[] nums) {
HashSet<Integer> hashSet = new HashSet<>();
for(int i = 0;i < nums.length;i++){
hashSet.add(nums[i]);
}
int res = 1;
for(int x:hashSet){
if(hashSet.contains(x-1))continue;
int y = x+1;
while (hashSet.contains(y))y++;
res = Math.max(res,y-1);
}
return res;
}
}
//O(n)+O(2n) = O(n)
//第二个循环从整体来看,每个元素至多遍历两次:在外层循环中遍历一次,在内层循环中遍历一次
//比如 nums=[1,2,3,4],4个元素在外层都被遍历了,在内层从1开始也都遍历了,但不会被遍历第3次