LeetCode202

- 快乐数
- 使用Set,循环出现就不是快乐数

LeetCode349
LeetCode350
- 数组交集
- 使用数组映射
This commit is contained in:
whai 2024-01-02 17:42:26 +08:00
parent 48a3b2f043
commit c7ed23b029
3 changed files with 344 additions and 0 deletions

View File

@ -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<Integer> 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<Integer> 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;
}
}
}

View File

@ -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<Integer> target = new HashSet<>();
HashSet<Integer> 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<Integer>() {
@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<Integer> 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();
}
}
}

View File

@ -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<Integer> 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);
}
}
}