leetcode.233,剑指offer.43:1~n整数中1出现的次数

输入一个整数 n ,求1~n这n个整数的十进制表示中1出现的次数。

例如,输入12,1~12这些整数中包含1 的数字有1、10、11和12,1一共出现了5次。

示例 1:

输入:n = 12
输出:5
示例 2:

输入:n = 13
输出:6

限制:

1 <= n < 2^31
注意:本题与主站 233 题相同:https://leetcode-cn.com/problems/number-of-digit-one/

通过次数11,764提交次数25,996

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/1nzheng-shu-zhong-1chu-xian-de-ci-shu-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路:
找规律,找规律的题真是难做,见过就会,没见过就不会,希望自己能记住。这道题来说,对于一个数字例如2023,我们可以循环的查看每一位数字,并计算该为数字上1出现的次数。设置high,cur,low,digit,分别代表高位的数字,当前位的数字,低位的数字,和当前的位数。根据cur的不同情况可以判断当前位的1出现的次数,如果cur=0的时候,说明cur的低位不可能出现更多的1(在低位已经记录过的1之外的1),因此此时的1的个数只与高位和位数有关,比如当前是3位数,digit=100,高位为2,当前位为0,也就是说,在这个位置出现的1只能是11或者01,所以等于dight X high。如果cur=1,分析方法类似,不过此时需要考虑低位的情况,因为低位的所有数字都代表了当前位出现了一次1,所以此时的1出现次数为digithight+low+1,特别的,低位全为0也多了一次出现1的次数。如果cur>1,那么就代表这个位置可能出现1的次数只与位数有关,低位的1也能够全部出现,所以出现1的次数 = digit(high+1)。遍历n的每个位数,累计结果即可。
注:1. high,cur,low可以递推得到,high初始化为n/10,cur = n%10,low = 0;递推公式为,low+=cur*digit,cur = high%10,high = high/10
2. digit使用long类型以防止大数溢出。

class Solution {
public:
    int countDigitOne(int n) {
        int ret = 0;
        int high = n/10;
        int cur = n%10;
        int low = 0;
        long digit = 1;

        while(high!=0||cur!=0)
        {
            if(cur==0)
            {
                ret+=high*digit;
            }
            else if(cur==1)
            {
                ret+=high*digit+1+low;
            }
            else
            {
                ret+=(high+1)*digit;
            }
            low += cur*digit;
            cur = high%10;
            high = high/10;
            digit*=10;
        }

        return ret;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值