LeetCode202
- 快乐数 - 使用Set,循环出现就不是快乐数 LeetCode349 LeetCode350 - 数组交集 - 使用数组映射
This commit is contained in:
parent
48a3b2f043
commit
c7ed23b029
115
src/main/java/cn/whaifree/leetCode/Hash/LeetCode202.java
Normal file
115
src/main/java/cn/whaifree/leetCode/Hash/LeetCode202.java
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
89
src/main/java/cn/whaifree/leetCode/Hash/LeetCode349.java
Normal file
89
src/main/java/cn/whaifree/leetCode/Hash/LeetCode349.java
Normal 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();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
140
src/main/java/cn/whaifree/leetCode/Hash/LeetCode350.java
Normal file
140
src/main/java/cn/whaifree/leetCode/Hash/LeetCode350.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user