1.两数之和
给定一个整数数组 nums
和一个整数目标值 target
,请你在该数组中找出 和为目标值 target
的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。你可以按任意顺序返回答案。
思路:使用哈希表存储数和对应下标,遍历的同时进行寻找
class Solution {
public int[] twoSum(int[] nums, int target) {
// 使用HashMap来存储数组中的元素及其对应的索引
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
// 计算当前元素与目标值的差值
int complement = target - nums[i];
// 检查HashMap中是否已经存在这个差值
if (map.containsKey(complement)) {
// 如果存在,说明找到了两个数的和等于目标值
// 返回这两个数的索引
return new int[]{map.get(complement), i};
}
// 如果不存在,将当前元素及其索引存入HashMap
map.put(nums[i], i);
}
// 如果遍历完数组仍未找到满足条件的两个数,返回空数组
return new int[0];
}
}
49.字母异位词分组
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的所有字母得到的一个新单词。
思路:将每个字符串排序后作为键,所有排序后得到相同键的字符串即为一组异位词。
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
// 创建一个哈希映射,键是排序后的字符串,值是所有对应的异位词
Map<String, List<String>> map = new HashMap<>();
List<List<String>> res = new ArrayList<>(); // 用于存储最终的分组结果
// 遍历输入的字符串数组
for (String str : strs) {
// 将当前字符串转换为排序后的键
String key = getKey(str);
// 检查哈希映射中是否已经存在该键
if (map.containsKey(key)) {
// 如果存在,直接将当前字符串添加到对应的列表中
List<String> list = map.get(key);
list.add(str);
} else {
// 如果不存在,创建一个新的列表,将当前字符串加入,并将键值对存入哈希映射
List<String> list = new ArrayList<>();
list.add(str);
map.put(key, list);
res.add(list); // 同时将该列表加入到结果列表中
}
}
// 返回最终的分组结果
return res;
}
// 辅助方法:将字符串排序后生成键
public String getKey(String str) {
// 将字符串转换为字符数组
char[] array = str.toCharArray();
// 对字符数组进行排序
Arrays.sort(array);
// 将排序后的字符数组重新转换为字符串作为键
return new String(array);
}
}
128. 最长连续序列
给定一个未排序的整数数组 nums
,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。
请你设计并实现时间复杂度为 O(n)
的算法解决此问题。
哈希法:对于nums中的元素x,以x为起点,不断查找下一个数x+1,x+2,⋯是否在nums中,并统计序列的长度。
class Solution {
public int longestConsecutive(int[] nums) {
int ans = 0;
Set<Integer> st = new HashSet<>();
for (int num : nums) {
st.add(num); // 把 nums 转成哈希集合
}
for (int x : st) { // 遍历哈希集合
if (st.contains(x - 1)) {
continue;
}
// x 是序列的起点
int y = x + 1;
while (st.contains(y)) { // 不断查找下一个数是否在哈希集合中
y++;
}
// 循环结束后,y-1 是最后一个在哈希集合中的数
ans = Math.max(ans, y - x); // 从 x 到 y-1 一共 y-x 个数
}
return ans;
}
}
排序
class Solution {
public int longestConsecutive(int[] nums) {
Arrays.sort(nums);// 排序数组
int maxCount = 1; // 最长连续序列长度
int count = 1; // 当前连续序列长度
if(nums.length == 0){
return 0;
}
for(int i = 0;i < nums.length - 1;i++){
if(nums[i] == nums[i + 1]){
// 忽略重复的数字
continue;
}
else if(nums[i + 1] - nums[i] == 1){
// 如果当前数字与下一个数字连续,增加计数
count++;
}
else{
// 不连续时,更新最大长度并重置计数
maxCount = Math.max(maxCount, count);
count = 1;
}
}
// 最后一次更新最大长度
maxCount = Math.max(maxCount, count);
return maxCount;
}
}