欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > 数据结构-哈西表笔记

数据结构-哈西表笔记

2025/4/20 13:24:50 来源:https://blog.csdn.net/2302_80490510/article/details/142673605  浏览:    关键词:数据结构-哈西表笔记

自定义26位字母哈西表

有效的字母异位词

242. 有效的字母异位词 - 力扣(LeetCode)

class Solution {public boolean isAnagram(String s, String t) {// 获取字符串 s 和 t 的长度int sLen = s.length();int tLen = t.length();// 如果两个字符串的长度不相等,则它们不可能是字母异位词if (sLen != tLen) {return false;}// 创建一个大小为 26 的数组 count 来统计每个字母出现的次数// 数组的索引 0-25 对应字母 'a'-'z'int count[] = new int[26];// 遍历字符串 s,并更新 count 数组// 对于 s 中的每个字符,计算其相对于 'a' 的索引位置,并将该位置的计数器加 1for (int i = 0; i < sLen; i++) {count[s.charAt(i) - 'a']++;}// 遍历字符串 t,检查每个字符在 count 数组中的计数for (int i = 0; i < tLen; i++) {// 如果 t 中的某个字符的计数已经为 0 或小于 0,说明它在 s 中不存在// 或者 s 中该字符出现的次数不足,直接返回 falseif (count[t.charAt(i) - 'a'] <= 0) {return false;}// 对于 t 中的每个字符,计算其索引位置,并将该位置的计数器减 1count[t.charAt(i) - 'a']--;}// 如果所有字符的出现次数都能相互抵消,说明 s 和 t 是字母异位词return true;}
}

赎金信

383. 赎金信 - 力扣(LeetCode)

class Solution {public boolean canConstruct(String ransomNote, String magazine) {// 不需要检查长度是否相等,题目并未要求int[] map = new int[26]; // 长度为26的数组,用于记录字符次数// 遍历 `magazine`,将每个字符出现的次数记录到 `map` 中。for(int i = 0; i < magazine.length(); i++){map[magazine.charAt(i) - 'a']++;  // 累加 magazine 中字符的出现次数}// 遍历 `ransomNote`,减少对应字符的计数。for(int i = 0; i < ransomNote.length(); i++){map[ransomNote.charAt(i) - 'a']--; // 减少 ransomNote 中字符的计数// 如果某个字符在 `magazine` 中的数量不足以构造 `ransomNote`,返回 falseif(map[ransomNote.charAt(i) - 'a'] < 0){return false;}}return true; // 能够成功构造则返回 true}
}

java自带hashset

两个数组的交集

349. 两个数组的交集 - 力扣(LeetCode)

class Solution {public int[] intersection(int[] nums1, int[] nums2) {// 创建一个 HashSet 存储 nums1 中的所有元素,避免重复Set<Integer> hashset1 = new HashSet<>();// 创建另一个 HashSet 存储 nums2 中与 nums1 交集的元素Set<Integer> hashset2 = new HashSet<>();// 遍历 nums1 数组,并将其所有元素添加到 hashset1 中for (int i = 0; i < nums1.length; i++) {hashset1.add(nums1[i]);  // HashSet 自动去重}// 遍历 nums2 数组,检查 hashset1 是否包含 nums2 中的元素// 如果包含,则该元素为交集,将其添加到 hashset2 中for (int i = 0; i < nums2.length; i++) {if (hashset1.contains(nums2[i])) {hashset2.add(nums2[i]);  // 只添加交集部分的元素}}// 将 hashset2 中的元素转换为数组形式,返回交集结果int ret[] = new int[hashset2.size()];  // 初始化结果数组,大小为交集元素的个数int i = 0;for (int temp : hashset2) {ret[i] = temp;  // 将 HashSet 中的元素逐一存入数组i++;}return ret;  // 返回最终的交集数组}
}

快乐数

202. 快乐数 - 力扣(LeetCode)

class Solution {public boolean isHappy(int n) {// 创建一个 HashSet 来记录已经计算过的数字,防止进入无限循环Set<Integer> hashset = new HashSet<>();// 循环条件:n 不等于 1 且 n 不在 hashset 中时继续循环while (n != 1 && !hashset.contains(n)) {// 将当前数字 n 加入 hashset,表示已经访问过hashset.add(n);// 计算 n 的各位数字的平方和,更新 nn = isHappySum(n);}// 如果最终 n 等于 1,则返回 true,表示该数字是快乐数;否则返回 falsereturn n == 1;}// 计算数字 n 的各位数字平方和的函数int isHappySum(int n) {int sum = 0;// 当 n > 0 时,不断取出各位数字并计算它们的平方while (n > 0) {int temp = n % 10;  // 取出 n 的最后一位数字sum += temp * temp;  // 计算该位数字的平方并累加到 sumn /= 10;  // 去掉最后一位数字}// 返回各位数字平方和return sum;}
}

哈希表HashMap

两数之和

1. 两数之和 - 力扣(LeetCode)

import java.util.HashMap;class Solution {public int[] twoSum(int[] nums, int target) {// 创建一个长度为2的数组,用于存放结果int ret[] = new int[2];// 创建一个哈希表,用于存储数组元素及其对应的索引HashMap<Integer, Integer> map = new HashMap<>();// 遍历输入数组,将每个元素及其索引存入哈希表for (int i = 0; i < nums.length; i++) {map.put(nums[i], i);}// 再次遍历输入数组,寻找两个数的和等于目标值for (int i = 0; i < nums.length; i++) {// 计算当前元素所需的另一半int temp = target - nums[i];// 检查哈希表中是否存在另一半,且它的索引不是当前元素的索引if (map.containsKey(temp) && map.get(temp) != i) {// 找到满足条件的两个元素,存入结果数组ret[0] = i;               // 当前元素的索引ret[1] = map.get(temp);  // 另一半的索引break;                   // 找到结果后跳出循环}}return ret; // 返回结果数组}
}

四数相加II

454. 四数相加 II - 力扣(LeetCode)

class Solution {public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {// 创建一个 HashMap 用于存储 nums1 和 nums2 的所有可能和及其出现的次数HashMap<Integer, Integer> map = new HashMap<>();int ret = 0; // 用于存储符合条件的四元组数量// 遍历 nums1 和 nums2 以计算所有可能的和for (int i = 0; i < nums1.length; i++) {for (int j = 0; j < nums2.length; j++) {// 计算 nums1[i] 和 nums2[j] 的和int temp = nums1[i] + nums2[j];// 如果 map 中已经存在该和,则将其计数加一if (map.containsKey(temp)) {map.put(temp, map.get(temp) + 1);} else {// 否则,将该和加入 map,并初始化计数为 1map.put(temp, 1);}}}// 遍历 nums3 和 nums4 以查找与 map 中的和匹配的元素for (int i = 0; i < nums3.length; i++) {for (int j = 0; j < nums4.length; j++) {// 计算 - (nums3[i] + nums4[j]),以便与 map 中的和进行匹配int temp = -nums3[i] - nums4[j];// 如果 map 中存在这个和,则将该和对应的计数加到 ret 中if (map.containsKey(temp)) {ret += map.get(temp);}}}// 返回符合条件的四元组的总数return ret;}
}

双指针

三数之和(难)

难在去重。如果不用去重就可以用哈希表

15. 三数之和 - 力扣(LeetCode)

class Solution {public List<List<Integer>> threeSum(int[] nums) {// 初始化结果列表,用来存储所有符合条件的三元组List<List<Integer>> ret = new ArrayList<>();// 首先对输入数组进行排序,这样我们可以利用排序后的性质来避免重复和进行双指针操作Arrays.sort(nums);// 遍历排序后的数组,i 是第一个选定的数,遍历数组中所有可能的第一个数for (int i = 0; i < nums.length; i++) {// 如果当前数大于0,则没有必要继续查找,因为在排序数组中,后续的数也都大于0,三数之和不可能为0if (nums[i] > 0) {break;}// 跳过重复的数值,避免结果中出现重复的三元组if (i > 0 && nums[i] == nums[i - 1]) {continue;}// 设置双指针,left 指向当前数之后的元素,right 指向数组末尾int left = i + 1;int right = nums.length - 1;// 使用双指针方法寻找三个数的和为0的组合while (left < right) {// 计算当前三个数的和int sum = nums[i] + nums[left] + nums[right];// 如果和大于0,说明右指针处的数太大,需要左移右指针if (sum > 0) {right--;// 如果和小于0,说明左指针处的数太小,需要右移左指针} else if (sum < 0) {left++;// 如果和等于0,找到了一个符合条件的三元组} else {// 将找到的三元组加入结果列表ret.add(Arrays.asList(nums[i], nums[left], nums[right]));// 为了避免重复的三元组,继续移动左指针,跳过所有重复的左边元素while (left < right && nums[left] == nums[left + 1]) {left++;}// 同样,继续移动右指针,跳过所有重复的右边元素while (left < right && nums[right] == nums[right - 1]) {right--;}// 在找到一个三元组后,继续尝试其他可能性,因此移动双指针left++;right--;}}}// 返回所有找到的不重复的三元组return ret;}
}

四数之和(难)

. - 力扣(LeetCode)

class Solution {public List<List<Integer>> fourSum(int[] nums, int target) {// 这个列表将存储最终的四元组结果List<List<Integer>> ret = new ArrayList<>();// 排序输入数组,以便于避免重复并使用双指针技术Arrays.sort(nums);// 遍历数组,选择四元组中的第一个数字for (int i = 0; i < nums.length; i++) {// 如果当前数字大于目标值且非负,可以提前结束if (nums[i] > target && nums[i] >= 0) {break;}// 跳过第一个数字的重复项if (i > 0 && nums[i] == nums[i - 1]) {continue;}// 遍历选择第二个数字for (int j = i + 1; j < nums.length; j++) {// 检查前两个数字的和是否已经超过目标值if (nums[i] + nums[j] > target && nums[i] + nums[j] >= 0) {break;}// 跳过第二个数字的重复项if (j > i + 1 && nums[j] == nums[j - 1]) {continue;}// 设置两个指针以查找剩下的两个数字int left = j + 1;int right = nums.length - 1;// 使用双指针查找剩下的两个数字while (left < right) {// 计算四个数字的和int sum = nums[i] + nums[j] + nums[left] + nums[right];// 如果和小于目标值,移动左指针向右if (sum < target) {left++;}// 如果和大于目标值,移动右指针向左else if (sum > target) {right--;}// 如果和等于目标值,找到一个四元组else {// 将四元组添加到结果列表ret.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));// 跳过第三个数字的重复项while (left < right && nums[left] == nums[left + 1]) {left++;}// 跳过第四个数字的重复项while (left < right && nums[right] == nums[right - 1]) {right--;}// 找到有效的四元组后,移动两个指针left++;right--;}}}}// 返回唯一四元组的列表return ret;}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词