// Source : https://leetcode.cn/problems/count-largest-group/
// Date : 2022-5-9
/**************************************************************************************
给你一个整数 n 。请你先求出从 1 到 n 的每个整数 10 进制表示下的数位和(每一位上的数字相加),然后把数位和相等的数字放到同一个组中。
请你统计每个组中的数字数目,并返回数字数目并列最多的组有多少个。
示例 1:
输入:n = 13
输出:4
解释:总共有 9 个组,将 1 到 13 按数位求和后这些组分别是:
[1,10],[2,11],[3,12],[4,13],[5],[6],[7],[8],[9]。总共有 4 个组拥有的数字并列最多。
示例 2:
输入:n = 2
输出:2
解释:总共有 2 个大小为 1 的组 [1],[2]。
示例 3:
输入:n = 15
输出:6
示例 4:
输入:n = 24
输出:5
提示:
1 <= n <= 10^4
**************************************************************************************/
/*******************************************************************************************************
题目分析:首先计算每个元素的数位和,然后将数位和对应的出现次数进行统计(本来是利用哈希表将元素与对应的数位和进行统计),然后只需要将最大的数位进行输出即可。这里要注意的是while循环应该将循环遍历用另一个变量去代替而不是仅仅用原始的循环变量去进行数位和的操作(该操作会导致死循环)。
********************************************************************************************************/
class Solution {
public:
int countLargestGroup(int n) {
// 记录每个元素的数位和
unordered_map<int, int> cnt;
int max_cnt = 0;
for(int i = 1;i < n + 1;++i)
{
// 记录数位和(如果在外部定义的话需要每次执行完毕之后将其清零,太麻烦)
int sum = 0;
//这里不能直接使用i,这会导致i一直为0,从而死循环
int ii = i;
// 取出数字n的每个位置上的数字,以计算数位和
while(ii)
{
sum += ii % 10;
ii /= 10;
}
// 这里可以直接计算该数字的次数的出现次数,而不仅仅是只计算该元素的出现次数
++cnt[sum];
max_cnt = max(cnt[sum], max_cnt);
}
int res = 0;
for(auto& it : cnt)
{
if(it.second == max_cnt)
++res;
}
return res;
}
};