[CareerCup] 18.4 Count Number of Two 统计数字2的个数

18.4 Write a method to count the number of 2s between 0 and n.

这道题给了我们一个整数n,让我们求[0,n]区间内所有2出现的个数,比如如果n=20,那么满足题意的是2, 12, 20,那么返回3即可。LeetCode上有一道很类似的题Factorial Trailing Zeroes,但是那道题求5的个数还包括了因子中的5,比如10里面也有5,这是两题的不同之处。那么首先这题可以用brute force来解,我们对区间内的每一个数字都调用一个函数,用来统计该数字中2出现的个数。而统计一个数字各位上而出现的个数很简单,就是平移位,对10取余,如果为2,则计数器自增1,然后此数自除以10,直至为0停止,参见代码如下:

解法一:

int count_number_2(int num) {
    int res = 0;
    while (num > 0) {
        if (num % 10 == 2) ++res;
        num /= 10;
    }
    return res;
}

int count_in_range(int num) {
    int res = 0;
    for (int i = 2; i <= num; ++i) {
        res += count_number_2(i);
    }
    return res;
}

其实这道题还有更好的办法,我们不是在区间里一个数一个数的找2,而是按位来找,比如我们先来列出一部分序列:

0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
...
110 111 112 113 114 115 116 117 118 119

我们发现最低位出现2的频率是每10个数字出现1个,我们大概可以分为三种情况来讨论,digit < 2, digti = 2, 和digit > 2。

解法二:

int count_in_range_as_digit(int num, int d) {
    int power_of_10 = pow(10, d);
    int next_power_of_10 = power_of_10 * 10;
    int right = num % power_of_10;
    int round_down = num - num % next_power_of_10;
    int round_up = round_down + next_power_of_10;
    int digit = (num / power_of_10) % 10;
    if (digit < 2) return round_down / 10;
    else if (digit == 2) return round_down / 10 + right + 1;
    else return round_up / 10;
}

int count_in_range(int num) {
    int res = 0;
    int len = to_string(num).size();
    for (int i = 0; i < len; ++i) {
        res += count_in_range_as_digit(num, i);
    }
    return res;
}

CareerCup All in One 题目汇总

时间: 2024-10-01 04:52:54

[CareerCup] 18.4 Count Number of Two 统计数字2的个数的相关文章

[LeetCode] Number of Digit One 数字1的个数

Given an integer n, count the total number of digit 1 appearing in all non-negative integers less than or equal to n. For example: Given n = 13, Return 6, because digit 1 occurred in the following numbers: 1, 10, 11, 12, 13. Hint: Beware of overflow.

[CareerCup] 18.3 Randomly Generate Integers 随机生成数字

18.3 Write a method to randomly generate a set of m integers from an array of size n. Each element must have equal probability of being chosen. 这道题让我们从一个数组中随机取出m个数字,要求每个数字被取出的概率相同,其实这道题用的是之前那道18.2 Shuffle Cards的方法,同样我们可以用递归和迭代两种方法来做,递归的思路还用的回溯法,回溯到i+

233 Number of Digit One 数字1的个数

给定一个整数 n,计算所有小于等于 n 的非负数中数字1出现的个数. 例如: 给定 n = 13, 返回 6,因为数字1出现在下数中出现:1,10,11,12,13. 详见:https://leetcode.com/problems/number-of-digit-one/description/ 方法一: class Solution { public: int countDigitOne(int n) { int cnt=0; for(long long m=1;m<=n;m*=10) {

[Coding Made Simple] Count Number of Binary Tree Possible given Preorder Sequence

Count Number of Binary Tree Possible given Preorder Sequence. For example, given preorder sequence of {10, 11, 9, 12, 13, 14}, the total possible number of binary trees is 42. Solution 1. Recursion Since we are only trying to find possbile binary tre

统计数字noip2007

7909:统计数字 总时间限制:  1000ms 内存限制:  65536kB 描述 某次科研调查时得到了n个自然数,每个数均不超过1500000000(1.5*109).已知不相同的数不超过10000个,现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出统计结果. 输入 包含n+1行:第一行是整数n,表示自然数的个数:第2~n+1每行一个自然数. 40%的数据满足:1<=n<=1000:80%的数据满足:1<=n<=50000:100%的数据满足:1<=n

统计数字

原题链接:https://www.luogu.org/problem/show?pid=1097 纪念开学第一天,随手A掉一道大水题纪念一下. 题意非常明显,让我们排序并且统计数字,但数据量较大. 一开始想到最暴力的桶排序,但发现桶排序开不了那么大的数组,A不掉. 遂STL快排解决之.问题就在如何统计重复数字上. 受到夏令营day1t1启发,快排后统计数字,每次和前边的进行比较,如果相等则当前数字重复,开一个vis数组打上标记,开一个b数组外带一个附带指针t,用来记录重复数字重复出现了几次.如果

7909:统计数字

7909:统计数字 查看 提交 统计 提问 总时间限制:  1000ms 内存限制:  65536kB 描述 某次科研调查时得到了n个自然数,每个数均不超过1500000000(1.5*109).已知不相同的数不超过10000个,现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出统计结果. 输入 包含n+1行:第一行是整数n,表示自然数的个数:第2~n+1每行一个自然数. 40%的数据满足:1<=n<=1000:80%的数据满足:1<=n<=50000:100%的

线段树求LIS并统计最长子序列个数

以下面的题目为例(题目和代码在最后面),给定一个数列(长度最大为10000),求出最长的先增后减子序列长度及个数.做法是先求出以每一个位置结尾的最长单增子序列长度以及以该位置开头的最长单减子序列长度,然后遍历所有位置找出最大先增后减子序列长度. 以最长单增序列(LIS)为例,由于不仅需要整个序列LIS的长度,还要保存以每个位置为结尾位置的LIS长度.记以a[i]结尾的LIS长度为dp[i],则 dp[i] = max{dp[j] | a[j] < a[i]} + 1 这就是一个RMQ问题,涉及单

统计数字在排序数组中出现的次数

统计一个数字在排序数组中出现的次数: 可定义一个用于统计数字个数的变量count,然后从前往后遍历数组,看是否与所求数字相等,如果相等,则count++: 下面贴出代码: public class Solution {     public int GetNumberOfK(int [] array , int k) {         int count = 0;        for(int i=0;i<array.length;i++){            if(array[i]==k