剑指offer 整数中1出现的次数(思维)

题目大意:

在[1,n]中,统计 所有 数位上包含的1数字,总共1的个数。比如 [1,11] 数位包含1的数字有: 1 10 11 总共有1 + 1 + 2 = 4 个1.

解题思路:

这题我们需要逐个数字位置上思考,个位对答案的贡献,十位对答案的贡献。。。

这里有一个key,我们这样最后答案的组成。比如数字 n = 2134:那么从个位开始看:所有的数字的组成可以看为 [0,2130] U [2131,2134],这样看有什么好处呢?

[0,2130]这部分对答案的贡献就是 213 个 1,得到个位的贡献的左半部分了!ans+=213. 那么我们再看 2131 2132 2133 2134,其中2131中的个位是1.所以 ans+= 1. 

同样对于十位对答案的贡献。我们发现可以拆分为[0,2100] U [2101,2134].

左半拆分 ans+=21 * 10(因为有21个可能你的十位是可以放置1的,同时每次放置在这里时答案就会+10. 所以是 21 * 10)

右半拆分 ans+= 10.

每一个数位一直讨论就可以了

class Solution {
public:
    vector<int> mv;
    int ans;
    int NumberOf1Between1AndN_Solution(int n)
    {
        int tmpn = n;
        ans = 0;
        while(tmpn){
            mv.push_back(tmpn%10);
            tmpn/=10;
        }
        int div = 10;
        int mul = 1;
        for(int i = 0;i<(int)mv.size();i++){
            ans += n/div*mul;
            if(mv[i]>1)ans+=mul;
            else if(mv[i] == 1)ans+=(n%(int)pow(10,i)+1);
            div*=10;
            mul*=10;
        }
        return ans;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值