今天晚上继续往下思考和学习了两道题目,分别是只出现一次的数字和求两个数组的交集,在之后查看题解的过程中发现这两道题都提到了使用哈希表的方法,但是对于哈希表自己并没有什么深入了解,所以决定这个周末抽出时间来仔细学习一下哈希表,然后尝试用文字记录一下自己的理解。
只出现一次的数字
这是第136题,意思是在一个数组中,只有一个数字是只出现一次的,其他的数字都只出现两次,求出只出现一次的数字。在看到这个题目是,脑中冒出的第一个想法是用昨天学到的方法对数组进行排序,随后遍历数组,对其中的元素相互进行比较,但在写的过程中发现遍历时需要将数字既和前一个元素比较,又与后一个元素比较,使得代码中的条件有点多。之后在查看题解后,当中提到有用哈希表(这周末的学习计划),还有使用位运算的方法,而且位运算的代码非常简洁。之前只在嵌入式开发中运用位运算的方法操作寄存器,并没有想过其他运用位运算的场景。异或运算具有三个性质,一个数与相同的数异或为0,与0异或为其本身,同时异或满足交换律和结合律,即将整个数组中的所有元素都进行异或操作,就可以等价于相同的数之间进行异或,再异或上只出现一次的数,也就相当于无数个0相互异或,在这基础上再异或上只出现一次的数,即0异或只出现一次的数,最后结果得到的是这个只出现一次的数。
int singleNumber(int* nums, int numsSize) {
int a = 0;
for (int i = 0; i < numsSize; i++)
{
a = a ^ nums[i];
}
return a;
}
数组交集
这是第350题,意思是有两个数组,求其交集,但是返回的数组中,每个元素出现的次数应该等于在两个数组中该元素出现次数的最低次,比如说元素2在数组A中出现1次,在数组B中出现2次,那在最后的结果数组中2应该出现1次。而且要求返回数组应该是通过malloc分配空间的,也就是分配两个数组中短的那个数组元素个数的空间。还是先将两个数组进行递增排序,随后分别遍历这两个数组,但是遍历两个数组的指针是不同步的,如果两个指针所指向的数相同,则将该数加入答案数组,如果两个指针指向的数字不同,则增加指向数字小的那个指针,再进行比较,以此类推,直到最后任一指针超出其数组范围。
#include<stdlib.h>
#include<math.h>
int cmp(const void* _a, const void* _b) {
int a = *(int*)_a, b = *(int*)_b;
return a - b;
}
int* intersect(int* nums1, int nums1Size, int* nums2, int nums2Size,
int* returnSize) {
qsort(nums1, nums1Size, sizeof(int), cmp);
qsort(nums2, nums2Size, sizeof(int), cmp);
*returnSize = 0;
int* ans = (int*)malloc(sizeof(int) * fmin(nums1Size, nums2Size));
int pnums1 = 0, pnums2 = 0;
while (pnums1 < nums1Size && pnums2 < nums2Size) {
if (nums1[pnums1] < nums2[pnums2]) {
pnums1++;
}
else if (nums1[pnums1] > nums2[pnums2]) {
pnums2++;
}
else {
ans[(*returnSize)++] = nums1[pnums1];
pnums1++;
pnums2++;
}
}
return ans;
}
希望自己坚持下去,持续积累!