剑指Offer43.1~n整数中1出现的次数

  • 剑指Offer43.1~n整数中1出现的次数

  • 题目:
    输入一个int n,输出整数1~n的10进制表示中1出现的次数;

  • 思路:
    1.逐位统计10进制下个位,十位,百位,。。。,最高位出现1的个数:时间O((log10 n) ^ 2):一个数字n共有log10 n位,每层循环内求l和r的操作也需要log10 n,因此共为(log10 n) ^ 2,空间为(log10 n),额外需要一个数组

class Solution {
public:
    int countDigitOne(int n) {//例如:n=13015
        if (!n) return 0;
        
        vector<int> number;//把数字n转成大小位log10 n的数组处理
        while (n) number.push_back(n % 10), n /= 10;//51031
        reverse(number.begin(), number.end());//13015
        int cnt = 0;
        for (int i = 0; i < number.size(); ++i) {//例如i=2
            int l = 0, r = 0, t = 1;//按i把数字n分成左半边数和右半边数, t是为了方便下面计算,实际就是10^(r的位数)
            for (int j = 0; j < i; ++j) l = l * 10 + number[j];//l = 13
            for (int j = i + 1; j < number.size(); ++j) r = r * 10 + number[j], t *= 10;//r = 15, t = 100

            if (number[i] == 0) cnt += l * t;//l取[00, 12],r取[00, 99]
            else if (number[i] == 1) cnt += l * t + r + 1;//l取[00,12],r取[000,99] 或 l==13,r取[00,15]
            else cnt += (l + 1) * t;//l取[00,13],r取[00,99]
        }

        return cnt;
    }
};

2.方法1的优化:时间为O(log10 n):随着cur的左移,l和r的随之改变,空间O(1):无需数组,改而维护cur,l,r

class Solution {
public:
    int countDigitOne(int n) {//例如:n=13015
        if (!n) return 0;
        
        int res = 0, t = 1;//t表示cur的右边数r的位数
        int cur = n % 10, l = n / 10, r = 0;//从个位开始,逐位统计
        while (l || cur) {//若只写l,会漏掉cur取最高位的情况
            if (cur == 0) res += l * t;//cur取百位0时,l取[00, 12], r取[00,99]
            else if (cur == 1) res += l * t + r + 1;//cur取十位1时,l取[000, 129],r取[0,9] 或l取[130],r取[0,5]
            else res += (l + 1) * t;//cur取千位3时,l取[0,1],r取[000,999]

            r += cur * t;//r向左多一位
            cur = l % 10;//cur左移一位
            l /= 10; //l少一位
            t *= 10;//t多乘个10
        }

        return res;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值