算法学习day06哈希表part01-202、349、1、242
package LeetCode.hashpart01; import java.util.HashSet; import java.util.Set; /** * 202. 快乐数 * 编写一个算法来判断一个数 n 是不是快乐数。 * * 「快乐数」定义为: * 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。 * 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。 * 如果这个过程 结果为 1,那么这个数就是快乐数。 * 如果 n 是 快乐数 就返回 true ;不是,则返回 false 。 * 示例: * 输入:n = 19 * 输出:true * 解释: * 1^2 + 9^2 = 82 * 8^2 + 2^2 = 68 * 6^2 + 8^2 = 100 * 1^2 + 0^2 + 0^2 = 1 * */ public class HappyNumber_202 { public static void main(String[] args) { boolean res = isHappy(19); System.out.println(res); } public static boolean isHappy(int n) { Set<Integer> record = new HashSet<>(); while (n != 1 && !record.contains(n)) { record.add(n); n = getNextNumber(n); } return n == 1; } public static int getNextNumber(int n) { int sum = 0; while (n > 0) { int temp = n % 10; sum += temp * temp; n = n / 10; } return sum; } }
package LeetCode.hashpart01; import java.util.HashSet; import java.util.Set; /** * 349. 两个数组的交集 * 给定两个数组 nums1 和 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序。 * 示例: * 输入:nums1 = [1,2,2,1], nums2 = [2,2] * 输出:[2] * */ public class IntersectionOfTwoArrays_349 { public static void main(String[] args) { int [] num1 = {1,3,5,6}; int [] num2 = {3,6,7,8}; int [] result = intersection(num1,num2); for (int i = 0; i < result.length; i++) { System.out.print(result[i]+" "); } } public static int[] intersection(int[] nums1, int[] nums2) { if (nums1 == null || nums1.length == 0 || nums2 == null || nums2.length == 0) { return new int[0]; } Set<Integer> set1 = new HashSet<>(); Set<Integer> resSet = new HashSet<>(); //遍历数组1 for (int i : nums1) { set1.add(i); } //遍历数组2的过程中判断哈希表中是否存在该元素 for (int i : nums2) { if (set1.contains(i)) { resSet.add(i); } } //方法1:将结果集合转为数组 return resSet.stream().mapToInt(x -> x).toArray(); } }
package LeetCode.hashpart01; import java.util.HashMap; import java.util.Map; /** * 1.两数之和: * 给定一个整数数组 nums和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那两个整数,并返回它们的数组下标。 * 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 * 你可以按任意顺序返回答案。 */ public class TwoSum_1 { public static void main(String[] args) { int[] arr = {1, 4, 6, 7, 8, 3}; int target = 15; int[] array = twoSum(arr, target); for (int i = 0; i < array.length; i++) { System.out.print(array[i] + " "); } } public static int[] twoSum(int[] nums, int target) { // 利用哈希表 时间复杂度O(n) Map<Integer, Integer> map = new HashMap<>(); for(int i = 0; i< nums.length; i++) { if(map.containsKey(target - nums[i])) { return new int[] {map.get(target-nums[i]),i}; } map.put(nums[i], i); } throw new IllegalArgumentException("No two sum solution"); } public int[] twoSum2(int[] nums, int target) { // 暴力穷举 时间复杂度O(n^2) int n = nums.length; for (int i = 0; i < n; ++i) { for (int j = i + 1; j < n; ++j) { if (nums[i] + nums[j] == target) { return new int[]{i, j}; } } } return new int[0]; } }
package LeetCode.hashpart01; /** * 242. 有效的字母异位词 * 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。 * 注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t互为字母异位词。 * */ /** * 思路: * 数组其实就是一个简单哈希表,而且这道题目中字符串只有小写字符,那么就可以定义一个数组,来记录字符串s里字符出现的次数。 * 定一个数组叫做record,大小为26 就可以了,初始化为0,因为字符a到字符z的ASCII也是26个连续的数值。 * * */ public class ValidAnagram_242 { public static void main(String[] args) { String s1 = "adja"; String s2 = "daaj"; boolean flag = is_anagram(s1,s2); System.out.println(flag); } public static boolean is_anagram(String s, String t) { int[] record = new int[26]; for (int i = 0; i < s.length(); i++) { record[s.charAt(i) - 'a']++; // 并不需要记住字符a的ASCII,只要求出一个相对数值就可以了 } for (int i = 0; i < t.length(); i++) { record[t.charAt(i) - 'a']--; } for (int count: record) { if (count != 0) { // record数组如果有的元素不为零0,说明字符串s和t 一定是谁多了字符或者谁少了字符。 return false; } } return true; // record数组所有元素都为零0,说明字符串s和t是字母异位词 } }
分类:
算法学习
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署