diff --git a/src/main/java/cn/whaifree/leetCode/Hash/LeetCode202.java b/src/main/java/cn/whaifree/leetCode/Hash/LeetCode202.java new file mode 100644 index 0000000..e3a3516 --- /dev/null +++ b/src/main/java/cn/whaifree/leetCode/Hash/LeetCode202.java @@ -0,0 +1,115 @@ +package cn.whaifree.leetCode.Hash; + +import org.junit.Test; + +import java.util.HashSet; +import java.util.Set; + +/** + * 202. 快乐数 + * 编写一个算法来判断一个数 n 是不是快乐数。 + * + * 「快乐数」 定义为: + * + * 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。 + * 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。 + * 如果这个过程 结果为 1,那么这个数就是快乐数。 + * 如果 n 是 快乐数 就返回 true ;不是,则返回 false 。 + * + * 示例 1: + * + * 输入:n = 19 + * 输出:true + * 解释: + * 12 + 92 = 82 + * 82 + 22 = 68 + * 62 + 82 = 100 + * 12 + 02 + 02 = 1 + * 示例 2: + * + * 输入:n = 2 + * 输出:false + * + * + * 提示: + * + * 1 <= n <= 231 - 1 + */ +public class LeetCode202 { + @Test + public void test() { + System.out.println(new Solution1().isHappy(2)); + } + + class Solution { + + Set set = new HashSet<>(); + + /** + * 计算的结果是否会重复出现,如果出现就证明会进入循环 + * @param n + * @return + */ + public boolean isHappy(int n) { + char[] chars = String.valueOf(n).toCharArray(); + int ans = 0; + +// StringBuilder stringBuilder = new StringBuilder("$"); + + for (char aChar : chars) { + aChar -= 48; + ans += aChar * aChar; + +// stringBuilder.append("+" + (int)aChar + "^2"); + } + +// stringBuilder.append("=" + ans + "$"); +// System.out.println(stringBuilder.toString()); + + + if (ans == 1) { + return true; + } else if (set.contains(ans)) { + return false; + } else { + set.add(ans); + return isHappy(ans); + } + } + } + + class Solution1 { + + + /** + * 计算的结果是否会重复出现,如果出现就证明会进入循环 + * @param n + * @return + */ + public boolean isHappy(int n) { + Set set = new HashSet<>(); + while (n != 1) { + n = getNextNumber(n); + if (set.contains(n)) { + return false; + } else { + set.add(n); + } + } + return true; + } + + public int getNextNumber(int n) { + int res = 0; + // 获取每个位 + while (n > 0) { + int i = n % 10; + res += i * i; + n /= 10; + } + return res; + } + + + } +} diff --git a/src/main/java/cn/whaifree/leetCode/Hash/LeetCode349.java b/src/main/java/cn/whaifree/leetCode/Hash/LeetCode349.java new file mode 100644 index 0000000..0bfa7ef --- /dev/null +++ b/src/main/java/cn/whaifree/leetCode/Hash/LeetCode349.java @@ -0,0 +1,89 @@ +package cn.whaifree.leetCode.Hash; + +import org.junit.Test; + +import java.util.*; +import java.util.function.ToIntFunction; + +/** + * 349. 两个数组的交集 + + * 给定两个数组 nums1 和 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。 + * + * + * 示例 1: + * + * 输入:nums1 = [1,2,2,1], nums2 = [2,2] + * 输出:[2] + * 示例 2: + * + * 输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4] + * 输出:[9,4] + * 解释:[4,9] 也是可通过的 + * + * + * 提示: + * + * 1 <= nums1.length, nums2.length <= 1000 + * 0 <= nums1[i], nums2[i] <= 1000 + */ +public class LeetCode349 { + + @Test + public void test() { + int[] nums1 = {9,4,9,8,4}; + int[] nums2 = {4,9,5}; + int[] res = new Solution1().intersection(nums1, nums2); + System.out.println(Arrays.toString(res)); + } + + + + class Solution { + public int[] intersection(int[] nums1, int[] nums2) { + + HashSet target = new HashSet<>(); + HashSet res = new HashSet<>(); + for (int i : nums1) { + target.add(i); + } + for (int i : nums2) { + if (target.contains(i)) { + res.add(i); + } + } + + return res.stream().mapToInt(new ToIntFunction() { + @Override + public int applyAsInt(Integer value) { + return value; + } + }).toArray(); + } + } + + class Solution1 { + public int[] intersection(int[] nums1, int[] nums2) { + + int[] A = new int[1001]; + int[] B = new int[1001]; + + for (int i : nums1) { + A[i]++; + } + for (int i : nums2) { + B[i]++; + } + + ArrayList res = new ArrayList<>(); + for (int i = 0; i < A.length; i++) { + if (A[i] != 0 && B[i] != 0) { + res.add(i); + } + } + + return res.stream().mapToInt(i -> i).toArray(); + + } + } +} diff --git a/src/main/java/cn/whaifree/leetCode/Hash/LeetCode350.java b/src/main/java/cn/whaifree/leetCode/Hash/LeetCode350.java new file mode 100644 index 0000000..3879e5e --- /dev/null +++ b/src/main/java/cn/whaifree/leetCode/Hash/LeetCode350.java @@ -0,0 +1,140 @@ +package cn.whaifree.leetCode.Hash; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; + +/** + * 给你两个整数数组 nums1 和 nums2 ,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值)。可以不考虑输出结果的顺序。* + * 示例 1: + * + * 输入:nums1 = [1,2,2,1], nums2 = [2,2] + * 输出:[2,2] + * 示例 2: + * 输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4] + * 输出:[4,9] + * + * 提示: + * + * 1 <= nums1.length, nums2.length <= 1000 + * 0 <= nums1[i], nums2[i] <= 1000 + * + * + * 进阶: + * + * 如果给定的数组已经排好序呢?你将如何优化你的算法? + * 如果 nums1 的大小比 nums2 小,哪种方法更优? + * 如果 nums2 的元素存储在磁盘上,内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办? + */ +public class LeetCode350 { + + @Test + public void test() { + int[] nums2 = {4,9,9,5}; + int[] nums1 = {9,4,9,8,4}; + int[] res = new Solution2().intersect(nums1, nums2); + System.out.println(Arrays.toString(res)); + } + + class Solution { + public int[] intersect(int[] nums1, int[] nums2) { + + int[] A = new int[1001]; + int[] B = new int[1001]; + for (int i : nums1) { + A[i]++; + } + for (int i : nums2) { + B[i]++; + } + + int[] ans = new int[1001]; + for (int i = 0; i < A.length; i++) { + ans[i] = Math.min(A[i], B[i]); + } + + + ArrayList objects = new ArrayList<>(); + for (int i = 0; i < ans.length; i++) { + for (int j = 0; j < ans[i]; j++) { + objects.add(i); + } + } + + return objects.stream().mapToInt(i -> i).toArray(); + } + } + + class Solution1 { + /** + * 计算两个数组的交集 + * @param nums1 第一个数组 + * @param nums2 第二个数组 + * @return 一个包含交集元素的数组 + */ + public int[] intersect(int[] nums1, int[] nums2) { + // 创建一个长度为1001的数组A,并初始化为0 + int[] A = new int[1001]; + + // 遍历第一个数组,将数组中的元素作为索引将对应索引的值加1 + for (int i : nums1) { + A[i]++; + } + + // 创建一个长度为第一个数组和第二个数组中较小长度的数组res,用于存储交集元素 + int[] res = new int[Math.min(nums1.length, nums2.length)]; + // 初始化索引为0 + int index = 0; + + // 遍历第二个数组,判断对应索引的值是否为0 + // 如果不为0,说明该元素在第一个数组中出现过,将该元素加入res数组中,并将对应索引的值减1 + // 同时将索引加1 + for (int i : nums2) { + if (A[i] != 0) { + res[index++] = i; + A[i]--; + } + } + + // 截取res数组中实际的长度,并返回结果 + return Arrays.copyOfRange(res, 0, index); + } + } + + class Solution2 { + /** + * 如果两个数组是有序的,则可以使用双指针的方法得到两个数组的交集。 + * @param nums1 第一个数组 长 + * @param nums2 第二个数组 短 + * @return 一个包含交集元素的数组 + */ + public int[] intersect(int[] nums1, int[] nums2) { + if (nums1.length < nums2.length) { + return intersect(nums2, nums1); + } + + // 排序 + Arrays.sort(nums1); + Arrays.sort(nums2); + + int[] res = new int[nums2.length]; + int index = 0 ; + int indexA = 0; + int indexB = 0; + // 使用两个指针,不断向前移动,如果哪个指针所指的数小了,就让他向前移动 + while (index < res.length && indexB < nums2.length && indexA < nums1.length) { + if (nums1[indexA] == nums2[indexB]) { + res[index++] = nums1[indexA++]; + indexB++; + } else if (nums1[indexA] < nums2[indexB]) { + indexA++; + } else if (nums1[indexA] > nums2[indexB]) { + indexB++; + } + } + + return Arrays.copyOfRange(res, 0, index); + } + } +}