两个数组的交集
反思:
简单的题目反而更容易错,因为轻敌,不仔细去思考
分析:
题目含义搞错:我一开始把题目理解错了,我认为交集就是相同的元素出现相同的次数,但是实际上这个题目求的交集就是交集,不用考虑重复数据
代码细节没有想到:其实就算我理解错了,我的理解是对题目要求的加强条件,应该运行没有问题,但是运行出现问题,因为我定义的统计结果的数组的长度是1010,是根据我定义的统计数组出现的次数的那个数组长度定义的,我这些数组长度的定义都不太规范,所以我返回的结果是交集和一堆0,这个地方必须根据交集的数目去定义这个存放结果的数组的数组长度
错误代码
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
int[] res=new int[1010];
int count=0;
int[] cnt1=new int[1010];
int[] cnt2=new int[1010];
for(int i=0;i<nums1.length;i++){
cnt1[nums1[i]]++;
}
for(int i=0;i<nums2.length;i++){
cnt2[nums2[i]]++;
}
for(int i=0;i<cnt1.length&&i<cnt2.length;i++){
if(cnt1[i]==cnt2[i]&&cnt1[i]!=0&&cnt2[i]!=0){
res[count++]=i;
}
}
return res;
}
}
正确代码:
方法一:Set集合
set集合不允许重复元素出现,正好这点性质方便我去统计交集的数据的数目,然后根据这个去定义返回结果的数组
class Solution{
public int[] intersection(int[] nums1, int[] nums2) {
if (nums1 == null || nums1.length == 0 || nums2 == null || nums2.length == 0) {
return new int[0];
}
Set<Integer> parentSet = new HashSet<>();
Set<Integer> childSet = new HashSet<>();
for (int num : nums1) {
parentSet.add(num);
}
for (int num : nums2) {
if (parentSet.contains(num)) {
childSet.add(num);
}
}
int[] resArr = new int[childSet.size()];
int index = 0;
for (int value : childSet) {
resArr[index++] = value;
}
return resArr;
}
}
方法二:双指针
这个双指针是两个指针在两个数组游走,不是前面数组题目用的双指针思想,可以用来扩宽思路
public int[] intersection(int[] nums1, int[] nums2) {
Set<Integer> set = new HashSet<>();
Arrays.sort(nums1);
Arrays.sort(nums2);
int i = 0, j = 0;
while (i < nums1.length && j < nums2.length) {
if (nums1[i] == nums2[j]) {
set.add(nums1[i]);
i++;
j++;
} else if (nums1[i] < nums2[j]) {
i++;
} else if (nums1[i] > nums2[j]) {
j++;
}
}
int[] res = new int[set.size()];
int index = 0;
for (int num : set) {
res[index++] = num;
}
return res;
}
但是这个地方我还是选择思路一,我更好理解,这个题目有一个变型题目,就是返回的结果是不含重复数据,但是如果要求返回交集可以带重复数据
变型题目
定义的时候使用list,所以可以存放重复的数据
public int[] intersect(int[] nums1, int[] nums2) {
List<Integer> list = new ArrayList<>();
Map<Integer, Integer> map = new HashMap<>();
for (int num : nums1) {
map.put(num, map.getOrDefault(num, 0) + 1);
}
for (int num : nums2) {
if (map.containsKey(num) && map.get(num) > 0) {
list.add(num);
map.put(num, map.get(num) - 1);
}
}
int[] res = new int[list.size()];
for (int i = 0; i < list.size(); i++) {
res[i] = list.get(i);
}
return res;
}
快乐数
分析题目:
链表找环
每个数字都会根据 各位平方和 指向另一个数字,所以从任意数字开始进行 各位平方和 的迭代操作,就相当于在链表上游走。如果 无限循环 但始终变不到 1,那说明肯定是链表游走到了环。
链表环
快慢指针
class Solution {
public boolean isHappy(int n) {
int fast = n;
int slow = n;
while (true) {
// 快慢指针异速前进
fast = getNext(fast);
fast = getNext(fast);
slow = getNext(slow);
if (fast == 1) return true;
if (fast == slow) return false;
}
}
// 取各位数字的平方和,即下一个数
private int getNext(int num) {
int sum = 0;
int localNum = num;
while (localNum > 0) {
int unitsDigit = localNum % 10; // 取个位数字
sum += unitsDigit * unitsDigit;
localNum /= 10;
}
return sum;
}
}