【剑指offer】整数中1出现的次数,C++实现

原创博文,转载请注明出处!
本题牛客网地址

博客文章索引地址

博客文章中代码的github地址

# 题目

image

# 思路

     分析1在数字中出现的规律。设数字N = abcde ,其中abcde分别为十进制中各位上的数字。如果要计算百位上1出现的次数,它要受到3方面的影响:百位上的数字,百位以下(低位)的数字,百位以上(高位)的数字。

① 如果百位上数字为0:百位上出现1的次数由更高位决定。

  例如:12013,则可以知道百位出现1的情况可能是:100~199,1100~1199 ,2100~2199,..., 11100~11199,一共1200个。可以看出是由更高位数字(12)决定,并且等于更高位数字(12)乘以 当前位数(100)。
② 如果百位上数字为1:百位上出现1的次数由高位和低位决定。

  例如:12113,则可以知道百位受高位影响出现的情况是:100~199, 1100~1199,  2100~2199,....,11100~11199,一共1200个。和上面情况一样,并且等于更高位数字(12)乘以 当前位数(100)。但同时它还受低位影响,百位出现1的情况是:12100~12113,一共14个,等于低位数字(13)+1。
③ 如果百位上数字大于1(2~9):百位上出现1的次数由更高位决定。

  例如:12213,则百位出现1的情况是:100~199,1100~1199,2100~2199, ..., 11100~11199, 12100~12199 ,一共有1300个,并且等于更高位数字+1(12+1)乘以当前位数(100)。

# 代码

class Solution {
public:
    int NumberOf1Between1AndN_Solution(int n)
    {
        int cnt =0;  // 1的个数
        int i=1;     // 当前位
        int cur = 0; // 当前位的值
        int high = 0;// 高位的值
        int low = 0; // 低位的值
        
        while(n/i != 0)
        {
            cur = n/i%10;
            high = n/i/10;
            low = n%i;
            
            // 如果cur=0,则cnt由高位决定
            if(cur == 0)
                cnt += high*i;
            
            // 如果cur=1,则cnt由高位和低位决定
            if(cur == 1)
                cnt += high*i + low+1;
            
            // 如果cur>1,则cnt由高位决定
            if(cur > 1)
                cnt += (high+1)*i;
            
            // 向前移位
            i = i*10;
        }
        
        return cnt;
    }
};

# 性能

  O(logn)

posted @ 2018-04-14 09:16  wanglei5205  阅读(404)  评论(0编辑  收藏  举报
levels of contents