Day05: 计数法(C语言)

分类: 365手机版游戏中心官网 时间: 2025-10-02 02:24:52 作者: admin 阅读: 2841
Day05: 计数法(C语言)

前言 如果你想学好算法和数据结构,请跟随他的脚步: 英雄哪里出来.

大家一起学习,一起打卡,一起成长。

目录

模板题目列表1748.唯一元素的和387.字符串中的第一个唯一字符1941. 检查是否所有字符出现次数相同448. 找到所有数组中消失的数字1512. 好数对的数目1711. 大餐计数

模板

如果题目是有关次数的问题,例如查找出只出现多少次的数字或字符,就可以用这个方法。

#define CAPACITY 100 //题目给出的最大范围

void FindValue(int* nums, int numsSize)

{

if (NULL == nums) //1

return;

int map[CAPACITY] = { 0 }; //2

//3

for (int i = 0; i < numsSize; ++i)

{

map[nums[i]]++;

}

//4 解决方案(题目要求)

}

判空申请一个用来计数的数组,范围太大可以动态申请遍历一遍,主要是统计次数

接下来的几个题目,基本都是按照这个方式来做的

题目列表

1748.唯一元素的和

链接: 唯一元素的和

#define CAPACITY 101

int sumOfUnique(int* nums, int numsSize)

{

if (NULL == nums) //1判空

return 0;

//2.根据题意给出的范围,申请一个计数的数组

//并初始化为0

int count[CAPACITY] = {0};

int ans = 0;

//3.计数

for (int i = 0; i < numsSize; ++i)

{

count[nums[i]]++;

}

//4.据题目要求写方案

for (int i = 0; i < CAPACITY; ++i)

{

if (count[i] == 1)

{

ans += i;

}

}

return ans;

}

387.字符串中的第一个唯一字符

链接: 字符串中的第一个唯一字符

#define CAPACITY 27

int firstUniqChar(char * s)

{

//和上面的解题步骤一样

if (NULL == s) //1

return -1;

int nums[CAPACITY] = {0}; //2

int len = strlen(s);

for (int i = 0; i < len; ++i) //3

{

nums[s[i] - 'a']++;

}

for (int i = 0; i < len; ++i) //4

{

if (nums[s[i] - 'a'] == 1)

{

return i;

}

}

return -1;

}

1941. 检查是否所有字符出现次数相同

链接: 1941. 检查是否所有字符出现次数相同.

#define CAPACITY 26

bool areOccurrencesEqual(char * s)

{

if (NULL == s)

return false;

int map[CAPACITY] = {0};

int count = 0;

for (int i = 0; i < strlen(s); ++i)

{

map[s[i] - 'a']++;

}

for (int i = 0; i < CAPACITY; ++i)

{

if (map[i] != 0 && map[i] != map[s[0] - 'a'])

{

return false;

}

}

return true;

}

448. 找到所有数组中消失的数字

链接: 448. 找到所有数组中消失的数字.

这个题比较特殊,第一是范围较大,可以采用动态申请空间,第二是要返回一个数组,申请动态数组,并根据题目要求返回这个数组的大小

int* findDisappearedNumbers(int* nums, int numsSize, int* returnSize)

{

*returnSize = 0;

if (NULL == nums)

return NULL;

//申请动态空间

int* map = (int*)malloc(sizeof(int) * (numsSize + 1));

memset(map, 0, sizeof(int) * (numsSize + 1));

//申请要返回的空间

int* ans = (int*)malloc(sizeof(int) * (numsSize + 1));

for (int i = 0; i < numsSize; ++i)

{

map[nums[i]]++;

}

for (int i = 1; i < numsSize + 1; ++i)

{

if (map[i] == 0)

{

ans[(*returnSize)++] = i;

}

}

free(map);

return ans;

}

1512. 好数对的数目

链接: 1512. 好数对的数目

暴力法 双重循环,根据题目要求来记数

int numIdenticalPairs(int* nums, int numsSize)

{

if (nums == NULL)

return -1;

int count = 0;

for (int i = 0; i < numsSize - 1; ++i)

{

for (int j = i + 1; j < numsSize; ++j)

{

if (nums[i] == nums[j])

{

count++;

}

}

}

return count;

}

哈希表

#define CAPACITY 101

int numIdenticalPairs(int* nums, int numsSize)

{

int map[CAPACITY] = {0};

int ans = 0;

for(int i = 0; i < numsSize; i++)

{

map[nums[i]]++;

ans += map[nums[i]] - 1;

}

return ans;

}

1711. 大餐计数

链接: 1711. 大餐计数

大餐 是指 恰好包含两道不同餐品 的一餐,其美味程度之和等于 2 的幂。

题目示例:

输入:deliciousness = [1,3,5,7,9]

输出:4

解释:大餐的美味程度组合为 (1,3) 、(1,7) 、(3,5) 和 (7,9) 。

它们各自的美味程度之和分别为 4 、8 、8 和 16 ,都是 2 的幂。

范围:

题目说出,两道不同餐品组合是2的幂,那反过来想,对每个元素,枚举出它和另一个数的所有和sum,即所有2的幂。那另一个数就是等于 other = sum - num

int map[(1<<21) + 1]; //根据题目要求写范围

int countPairs(int* deliciousness, int deliciousnessSize)

{

if (NULL == deliciousness)

return 0;

memset (map, 0, sizeof(map));

int sum = 0; //用来保存2的幂

int ans = 0; //返回的答案

for(int i = 0; i < deliciousnessSize; ++i)

{

for(sum = 1; sum <= (1<<21); sum *= 2)

{

int other = sum - deliciousness[i];

if (other < 0)

{

continue;

}

ans += map[other];

ans %= 1000000007;

}

map[deliciousness[i]]++;

}

return ans;

}

方法来源 个人感觉这个方法比官方答案更好理解

链接: 英雄哪里出来《算法零基础100讲》.

相关推荐