剑指offer (32) 从1到n整数中1的出现次数

题目:输入一个整数,求从1到n这个n个整数的十进制表示中1的出现次数

方法一:最直观的解法  T(n) = O(nlgn)

int NumberOf1Between1AndN_Solution1(unsigned int n)
{
    int number = 0;

    for(unsigned int i = 1; i <= n; ++ i)
        number += NumberOf1(i);

    return number;
}

int NumberOf1(unsigned int n)
{
    int number = 0;
    while(n)
    {
        if(n % 10 == 1)
            number ++;

        n = n / 10;
    }

    return number;
}

方法二:

假设N = abcde(N的十进制表示,e为个位)

如果要计算百位c出现1的次数,将会受到3个因素的影响:

(1) 百位上的数字

(2) 百位以下的数字(低位数字)

(3) 百位以上的数字(高位数字)

如果百位数字为0,百位出现1的次数取决于 其高位数字

比如 12013, 出现1的情况可能是:100-199  1100-1199  2100-2199 ..... 10100-10199  11100-11199

可以看到出现1时,低位(即cde)都是 100-199这100种情况,而高位(即ab两位)从 0,1,2,3...11 刚好为12对,即高位数字12

所以:这时百位出现1的次数:高位数字12 × 当前位数100 = 1200

如果百位数字为1,百位出现1的次数取决于 其高位数字和低位数字

比如12113,先按照上面一种情况所述:100-199  1100-1199  2100-2199 ..... 10100-10199  11100-11199

这个时候百位为1,则 还有其他情况可以出现1:12100  12101  12102  12103 .....12113 (注意到高两位都为12,低位从100到113,即低位13+1=14种情况)

所以:这时百位出现1的次数:高位数字12 × 当前位数100 + 低位数字13 + 1 = 1214

如果百位数字大于1,百位出现1的次数取决于 其高位数字

比如12213,按照第一种情况所述:100-199  1100-1199  2100-2199 ..... 10100-10199  11100-11199 12100-12199

注意:百位数字大于1,所以不要忘记了 12100-12199 这种情况

所以:这时百位出现1的次数:(高位数字12 + 1 )× 当前位数100 = 1300

int OneNum(const int num)
{
    assert(num >= 0);
    int factor = 1;
    int count = 0;
    int curNumber = 0;
    int highNumber = 0;
    int lowNumber = 0;
    while (num / factor != 0) {
        lowNumber  = num - (num / factor) * factor;  // 低位数字
        curNumber  = (num / factor) % 10;            // 当前位数字
        highNumber = (num / factor) / 10;            // 高位数字

        switch (curNumber) {
            case 0 :
            count += highNumber * factor;
            break;

            case 1 :
            count += highNumber * factor + lowNumber + 1;
            break;

            default :
            count += (highNumber + 1) * factor;
            break;
        }

        factor *= 10;
    }

    return count;
}

剑指offer (32) 从1到n整数中1的出现次数

时间: 2024-10-12 19:24:45

剑指offer (32) 从1到n整数中1的出现次数的相关文章

剑指offer(31)1~n整数中1出现的次数

题目描述 求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1.10.11.12.13因此共出现6次,但是对于后面问题他就没辙了.ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数. 题目分析 这题说实话挺难的,暴力解法比较简单,主要是想到时间复杂度更好的解法很难. 第一种暴力解法,也就是逐个判断. 第二种运用了根据位数来做,逐位求解,并且对于特殊情况做下判断. 主要注意下每位0,1,>

【剑指offer】43、1~n整数中1出现的次数

题目 输入一个整数,求1~n的整数十进制表示中1出现的次数.如12,有1,10,11,12,总共出现了5次. 思路 注意不是统计出现1的数字的多少,而是统计1出现了几次. 我们按位来分析 个位: 如果weight=0,则个位出现1的次数 = round 如果weight>=1,则个位出现1的次数=round + 1 十位: 如果weight=0,则次数 = round * base 如果weight=1,则次数 = round * base + former + 1  ( former = n

剑指OFFER----面试题43. 1~n整数中1出现的次数

链接:https://leetcode-cn.com/problems/1nzheng-shu-zhong-1chu-xian-de-ci-shu-lcof/ 代码: class Solution { public: int countDigitOne(int n) { vector<int> number; if (!n) return 0; while(n) number.push_back(n % 10), n/= 10; int res = 0; for (int i = number

【剑指Offer面试题】二维数组中的查找

下决心AC所有剑指offer面试题. 九度OJ面试题地址:http://ac.jobdu.com/hhtproblems.php 书籍:何海涛--<剑指Offer:名企面试官精讲典型编程题> 对于面试题,面试官往往更希望我们能提出优化方法,这样更能体现我们的思维能力以及传说中的"内功".所以做剑指offer要着重训练这方面,多总结多细究,总是有好处的.加油~ 二维数组中的查找 时间限制:1 秒内存限制:32 兆 特殊判题:否提交:19005解决:3642 题目描述: 在一个

【剑指offer】Q38:数字在数组中出现的次数

与折半查找是同一个模式,不同的是,在这里不在查找某个确定的值,而是查找确定值所在的上下边界. def getBounder(data, k, start, end, low_bound = False): if end < start : return -1 while start <= end: mid = ( start + end ) >> 1 if data[ mid ] > k: end = mid - 1 elif data[ mid ] < k: star

【剑指offer】删除在另一个字符串中出现的字符

转载请注明出处:http://blog.csdn.net/ns_code/article/details/27110873 剑指offer上的字符串相关题目. 题目:输入两个字符串,从第一字符串中删除第二个字符串中所有的字符.例如,输入"They are students."和"aeiou",则删除之后的第一个字符串变成"Thy r stdnts.". 这里主要要分析两个方面: 1.如何判断那些字符是需要删除的字符.同很多字符串问题一样,可以开辟

剑指 offer 第一题: 二维数组中的查找

打算写 图解剑指 offer 66 题 的系列文章,不知道大家有没有兴趣 ?? 题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 题目分析 图 1 如果没有头绪的话,很显然使用 暴力解法 是完全可以解决该问题的. 即遍历二维数组中的每一个元素,时间复杂度:O(n^2). 其实到这里我们就可以发现,使用这种暴力解法并没有充分利用题目给出的信息.这

剑指offer——32从上到下打印二叉树

题目描述 从上往下打印出二叉树的每个节点,同层节点从左至右打印. 题解: 就是简单的层序遍历 1 class Solution { 2 public: 3 vector<int> PrintFromTopToBottom(TreeNode* root) { 4 vector<int>res; 5 BFS(root, res); 6 return res; 7 } 8 void BFS(TreeNode *root, vector<int>&res) 9 { 10

剑指offer系列源码--二维数组中的查找

题目1384:二维数组中的查找 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:14827 解决:2888 题目描述: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 输入: 输入可能包含多个测试样例,对于每个测试案例, 输入的第一行为两个整数m和n(1<=m,n<=1000):代表将要输入的矩阵的行数和列数. 输入的第二行包括一个整数t(1<=t<=1