题目:
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
示例 1:
输入: s = "anagram", t = "nagaram"
输出: true
示例 2:
输入: s = "rat", t = "car"
输出: false
说明:
你可以假设字符串只包含小写字母。
进阶:
如果输入字符串包含 unicode 字符怎么办?你能否调整你的解法来应对这种情况?
答案:
//方法一:先排序 然后比较两个字符串是否完全相同
int compare(const void *a, const void *b)
{
return (*(char *)a - *(char *)b);
}
bool isAnagram(char * s, char * t)
{
if(strlen(s) != strlen(t))//长度不同直接返回
return false;
qsort(s, strlen(s), sizeof(char), compare);
qsort(t, strlen(t), sizeof(char), compare);
if(strcmp(s, t) == 0)
return true;
else
return false;
}
//方法二:用一个26个int大小的int数组,初始化为0
// 字符串s中出现的字母则让其对应的数+1
// 字符串t中出现的字母则让其对应的数-1
// 最后判断数组中的数若全为0则返回true 否则返回false
bool isAnagram(char * s, char * t){
if(strlen(s) != strlen(t))
return false;
int num[26] = {0};
int i = 0;
for(; s[i] != '\0'; i++)
{
num[s[i] - 'a'] ++;
num[t[i] - 'a'] --;
}
for(i = 0; i < 26; i++)
{
if(num[i] != 0)
return false;
}
return true;
}
若字符串中只包含小写字母,则两种方法都直观,容易理解,不过排序消耗的时间略长。
若字符串包含 unicode 字符排序应该还可以使用(只是猜测,没有验证),但是却无法使用方法二(固定大小的数组)来判断了,需要将方法二的固定大小数组改为哈希表。
题目
给定两个数组,编写一个函数来计算它们的交集。
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]
示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[9,4]
说明:
输出结果中的每个元素一定是唯一的。
我们可以不考虑输出结果的顺序。
答案
int compare(const void *a, const void *b)
{
return *(int *)a - *(int *)b;
}
int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
int *result = NULL;
int i = 0;
int j = 0;
int count = 0;
qsort(nums1, nums1Size, sizeof(int), compare);
qsort(nums2, nums2Size, sizeof(int), compare);
*returnSize = 0;
while(i < nums1Size && j < nums2Size)
{
if(nums1[i] == nums2[j])
{
if(result == NULL || nums1[i] != nums1[i - 1])
{
count ++;
result = (int *)realloc(result, count * sizeof(int));
result[count - 1] = nums1[i];
}
i++;
j++;
}
else if(nums1[i] > nums2[j])
{
j++;
}
else
{
i++;
}
}
*returnSize = count;
return result;
}
因为可以不考虑输出结果的顺序,所以又想到排序,排序后按照排好的顺序依次判断重复元素(注意去掉相同元素)。
题目
给定两个数组,编写一个函数来计算它们的交集。
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2,2]
示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[4,9]
说明:
输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。
我们可以不考虑输出结果的顺序。
进阶:
如果给定的数组已经排好序呢?你将如何优化你的算法?
如果 nums1 的大小比 nums2 小很多,哪种方法更优?
如果 nums2 的元素存储在磁盘上,磁盘内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?
答案
int compare(const void *a, const void *b)
{
const int *num1 = (const int *)a;
const int *num2 = (const int *)b;
if(*num1 > *num2)
return 1;
else if(*num1 < *num2)
return -1;
else
return 0;
}
int* intersect(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
int *result = NULL;
int i = 0;
int j = 0;
qsort(nums1, nums1Size, sizeof(int), compare);
qsort(nums2, nums2Size, sizeof(int), compare);
*returnSize = 0;
while(i < nums1Size && j < nums2Size)
{
if(nums1[i] == nums2[j])
{
(*returnSize) ++;
result = (int *)realloc(result, (*returnSize) * sizeof(int));
result[*returnSize - 1] = nums1[i];
i++;
j++;
}
else if(nums1[i] > nums2[j])
{
j++;
}
else
{
i++;
}
}
return result;
}
看到这个题,以为和上一题一模一样,甚至还少了去重的操作,我开心的笑了,写完后,力扣跟我开了小小的玩笑,报错了(当时(*returnSize) ++;没加括号),我懵了,去编译器调试自己的代码发现,*returnSize的值是随机的,后来各种查才发现*returnSize++实际上是 *(returnSize++)而不是(*returnSize) ++, 原因是虽然自增运算符++与优先级相同 但是是自右向左结合的。
还有一个bug就是上一题的compare函数相减时可能会出现int类型溢出的问题。
ps:为什么题刷的好好的突然提交不了了!!!