今日题解
因为想锻炼一下自己的英语阅读能力,所以就把语言调成了英文,每道题都有链接看不太明白的可以点击链接看中文的题目。
1748. Sum of Unique Elements
Constraints:
1 <= nums.length <= 100
1 <= nums[i] <= 100
这道题是一道十分基础的计数题,并且数据范围也比较小,可以利用数组下标来记录每个数出现的次数。
代码如下:
int sumOfUnique(int* nums, int numsSize){
//元素大小在1-100,所以我们定义一个长度为101的数组
int arr[101];
memset(arr, 0, sizeof(arr));//将数组元素进行初始化
for(int i = 0; i < numsSize; i++){
arr[nums[i]]++;
}
int cnt = 0;
for(int i = 0; i < 101; i++){
if(arr[i] == 1){
cnt+=i;
}
}
return cnt;
}
387. First Unique Character in a String
这道题考的是对ASCII码表的使用,我们可以通过数组arr[26]来记录每个字符出现的次数。
代码如下:
int firstUniqChar(char * s){
int arr[26];
memset(arr, 0, sizeof(arr));
int n = strlen(s);
for(int i = 0; i < n; i++){
//将s[i] - 'a'就可以将字符s[i]转化为0-25的下标来表示
arr[s[i] - 'a']++;
}
for(int i = 0; i < n; i++){
if(arr[s[i] - 'a'] == 1){
return i;
}
}
return -1;
}
1941. Check if All Characters Have Equal Number of Occurrences
Constraints:
1 <= s.length <= 1000
s consists of lowercase English letters.
这道题的做法和上道题差不多,也是用一个数组arr[26]来记录每个字符出现的次数,并且比较每个字符出现的次数是否相同,但是在计算的同时我们也要用一个变量记录更新某个字符出现的次数。
代码如下:
bool areOccurrencesEqual(char * s){
int arr[26];
memset(arr, 0, sizeof(arr));
int len = strlen(s);
//用来记录某个字符出现的次数
int n = 0;
for(int i = 0; i < len; i++){
arr[s[i] - 'a']++;
n = arr[s[i] - 'a'];
}
for(int i = 0; i < 26; i++){
if(arr[i] == 0){
continue;
}
else if(arr[i] != n){
return false;
}
}
return true;
}
448 Find All Numbers Disappeared in an Array
448.找到所有数组中消失的数
这道题可以用hash表的思路来记录nums数组中的数字因为数组元素的取值范围是[1,n],所以我们可以定义一个长度为n的数组来记录,这种解法的时间复杂度是O(n),空间复杂度也是O(n),但我们如何能够将空间复杂度降到O(1)呢?
这里我们可以考虑用nums本身来做hash表,我们可以将nums[i]+numsSize赋值给nums[nums[i] - 1],这样,每个出现过的数字所对应的下标的元素都会大于numsSize,最后在遍历nums数组,数据小于或等于numsSize所对应的下标+1就是该数组中所缺少的元素,但这样有会出现一个问题,因为nums中的元素是随机的,如果较大的数字出现在前面,就会将该数字所对应下标的较小数据给覆盖掉,这样就会遗漏一些数据,对于这个问题我们可以通过取模操作符来解决。
代码如下:
int* findDisappearedNumbers(int* nums, int numsSize, int* returnSize){
for(int i = 0; i < numsSize; i++){
int x = (nums[i] - 1) % numsSize;
nums[x] += numsSize;
}
int* arr = (int*) malloc (sizeof(int) * numsSize);
int n = 0;
for(int i = 0; i < numsSize; i++){
if(nums[i] <= numsSize){
arr[n++] = i + 1;
}
}
*returnSize = n;
return arr;
}
1512. Number of Good Pairs
这道题也是十分的简单,只需找出有多少对相等的数,方法也很多种,但由于数据量不大,所以我们就直接用暴力法即可。
代码如下:
int numIdenticalPairs(int* nums, int numsSize){
int num = 0;
for(int i = 0; i < numsSize; i++){
for(int j = i + 1; j < numsSize; j++){
if(nums[i] == nums[j]){
num++;
}
}
}
return num;
}
1711. Count Good Meals
1711.大餐计数
用例:
这道题的数据量比较大,如果直接用暴力法会超时,时间复杂度是O(n ^ 2),官方的题解是用哈希表来做,但这道题我更中意英雄哥的解法,题目要求我们找出数组内两个元素的和为2的幂,反过来我们可以用2的幂来减去数组的中的元素,先定义一个数组cnt[(1<<21) + 1],因为数据的范围是[1,2 ^ 20],所以两个数据的和最大不会超过2 ^ 21,具体操作如下:
int cnt[ (1<<21) + 1 ];
int countPairs(int* deliciousness, int deliciousnessSize){
memset(cnt, 0, sizeof(cnt));
int ret = 0;
for(int i = 0; i < deliciousnessSize; i++){
//j表示2的幂
for(int j = 1; j <= (1 << 21); j *= 2){
//dis表示差
int dis = j - deliciousness[i];
if(dis < 0){
continue;
}
//如果dis>0,则在ret上累加cnt[dis],
//cnt[dis],内的数据代表deliciousness中dis的个数
ret += cnt[dis];
ret %= 1000000007;
}
//更新dis的个数。
cnt[deliciousness[i]]++;
}
return ret;
}
//1000000007