1.哈希
两数之和
题目:
给定一个整数数组
nums和一个整数目标值target,请你在该数组中找出 和为目标值target的那 两个 整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。
你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9 输出:[0,1] 解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。示例 2:
输入:nums = [3,2,4], target = 6 输出:[1,2]示例 3:
输入:nums = [3,3], target = 6 输出:[0,1]
java
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] nums1 =new int[2];
for(int i=0;i<nums.length;i++){
for(int j=i+1;j<nums.length;j++){
if(nums[i]+nums[j]==target){
nums1[0]=i;
nums1[1]=j;
}
}
}
return nums1;
}
}
当前:枚举
建议:哈希表/数组
核心考察:利用哈希表空间换时间,快速查找互补数
java
class Solution {
public int[] twoSum(int[] nums, int target) {
// key:数组中的数字,value:数字对应的下标
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int curNum = nums[i];
// 算出需要匹配的另一半数字
int need = target - curNum;
// 哈希表中存在另一半,说明找到答案
if (map.containsKey(need)) {
// map.get(need) 是之前存的下标,i是当前下标
return new int[]{map.get(need), i};
}
// 没找到就把当前数字和下标存入map,供后面遍历匹配
map.put(curNum, i);
}
return new int[]{};
}
}
字母异位词分组
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
示例 1:
输入: strs = "eat", "tea", "tan", "ate", "nat", "bat"
输出:\["bat","nat","tan","ate","eat","tea"]
解释:
- 在 strs 中没有字符串可以通过重新排列来形成
"bat"。- 字符串
"nat"和"tan"是字母异位词,因为它们可以重新排列以形成彼此。- 字符串
"ate","eat"和"tea"是字母异位词,因为它们可以重新排列以形成彼此。示例 2:
输入: strs = ""
输出:\[""]
示例 3:
输入: strs = "a"
输出:\["a"]
java
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
// 1. 创建哈希表:key=排序后的字符串,value=同组异位词列表
Map<String, List<String>> map = new HashMap<>();
// 2. 遍历每一个单词
for (String str : strs) {
// 2.1 将字符串转为字符数组,排序
char[] charArr = str.toCharArray();
Arrays.sort(charArr);
// 排序后转回字符串,作为分组唯一key
String sortKey = new String(charArr);
// 2.2 如果map没有这个key,新建空列表
if (!map.containsKey(sortKey)) {
map.put(sortKey, new ArrayList<>());
}
// 2.3 取出列表,把当前单词加入
map.get(sortKey).add(str);
}
// 3. 将map中所有分组集合转为最终结果返回
return new ArrayList<>(map.values());
}
}
思路:
创建map
循环遍历每个字符串,将每个取出然后排序作为key,接着就对接下来的是一样排序的字符串就加上去该key的list,表示就new一个这个key的空集合,用于存放和他排序一样的字符串
最后new一个返回值将map返回
最长连续序列
给定一个未排序的整数数组
nums,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。请你设计并实现时间复杂度为
O(n)的算法解决此问题。示例 1:
输入:nums = [100,4,200,1,3,2] 输出:4 解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。示例 2:
输入:nums = [0,3,7,2,5,8,4,6,0,1] 输出:9示例 3:
输入:nums = [1,0,1,2] 输出:3提示:
0 <= nums.length <= 105-109 <= nums[i] <= 109
java
class Solution {
public int longestConsecutive(int[] nums) {
// 处理数组为空的边界
if (nums == null || nums.length == 0) {
return 0;
}
// 1. 创建哈希集合,存入所有数字,自动去重
Set<Integer> numSet = new HashSet<>();
for (int num : nums) {
numSet.add(num);
}
int maxLength = 0;
// 2. 遍历集合中每个数字
for (int x : numSet) {
// 判断:x-1不存在,说明x是连续序列起点
if (!numSet.contains(x - 1)) {
int currentNum = x;
int currentLen = 1;
// 不断往后找连续数字
while (numSet.contains(currentNum + 1)) {
currentNum++;
currentLen++;
}
// 更新最大长度
if (currentLen > maxLength) {
maxLength = currentLen;
}
}
}
return maxLength;
}
}
完整逻辑流程
- 数组为空直接返回 0;
- 创建 HashSet 存入所有数字,去重;
- 定义最长长度 maxLen=0;
- 遍历集合中每个数字 x:
- 如果集合不含 x-1 → x 是连续段起点
- 当前长度 curLen=1,current=x
- 循环判断 current+1 是否在集合:存在则 curLen++,current++
- 更新 maxLen
- 遍历结束返回 maxLen