zoukankan      html  css  js  c++  java
  • 整数中1出现的次数(从1到n整数中出现的次数)

    题目描述

    求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数(从1 到 n 中1出现的次数)。

     简单的方法:对10取模求得每一位的数,时间复杂度O(nlogn)

    class Solution {
    public:
        int NumberOf1Between1AndN_Solution(int n)
        {
            if(n <= 0) return 0;
            int sum = 0;
            while(n){
                sum += weishu(n);
                n--;
            }
            return sum;
        }
        int weishu(int n){
            int sum = 0;
            while(n){
                if(n % 10 == 1)
                    sum++;
                n /= 10;
            }
            return sum;
        }
    };

    或者将数字转为字符串,对每一位进行判断

    剑指offer的思路:利用数学规律

    这里要注意的是类似100这种情况还有首位为1的情况

    public class Solution {
        public int NumberOf1Between1AndN_Solution(int n) {
            if(n <= 0) return 0;
            String number = n+"";
            return NumberOf1("1",number,number.length());
        }
        public int NumberOf1(String startNum,String endNum,int endNumWei){
            if(endNumWei == 1)
                return 1;
            if(startNum == "1"){
                String subNum = endNum.substring(1);
                while(subNum.length()>0&&subNum.charAt(0) == '0'){
                    subNum = subNum.substring(1);
                }
                if(subNum.length()==0) {
                    int sumOne = 0;
                    for(int i=0;i<endNum.length();i++){
                        if(endNum.charAt(i)=='1')
                            sumOne++;
                    }
                    endNum = (strToint(endNum)-1)+"";
                    return sumOne + NumberOf1("1",endNum,endNum.length());
                }
                else
                    return NumberOf1(subNum,endNum,endNumWei) +
                        NumberOf1("1",subNum,subNum.length());
            }else{
                if(endNum.charAt(0) != '1')
                    return (int)(Math.pow(10.0,endNumWei-1) + ((int)endNum.charAt(0)-(int)('0')) * (endNumWei-1) * Math.pow(10.0,endNumWei-2));
                else{
    
                    return strToint(endNum.substring(1))+1 + (endNumWei-1) * (int)Math.pow(10.0,endNumWei-2);
                }
            }
        }
        public int strToint(String str){
            int sum = 0;
            for(int i=0;i<str.length();i++)
                sum = sum * 10 + (int)(str.charAt(i)-'0');
            return sum;
        }
    }

     还是没有书上的算法简洁:

    class Solution {
    public:
        int NumberOf1Between1AndN_Solution(int n)
        {
            if(n<=0) return 0;
            char strN[50];
            sprintf(strN, "%d", n);
            return NumberOf1(strN);
        }
        int NumberOf1(char* strN){
            if(*strN <'0'||*strN>'9')
                return 0;
            unsigned int len = static_cast<unsigned int>(strlen(strN));
            int first = *strN - '0';
            if(len == 1 && first == 0)
                return 0;
            if(len == 1 && first > 0)
                return 1;
            
            //计算首位为1的个数
            int numFirstDigit = 0;
            if(first == 1)
                numFirstDigit = atoi(strN+1)+1;
            else if(first > 1)
                numFirstDigit = (int)pow(10.0, len-1);
            int otherDigits = first *(len-1)*(int)pow(10.0, len-2);
            int recurisiveDigits = NumberOf1(strN+1);
            return numFirstDigit + otherDigits + recurisiveDigits;
        }
    };
  • 相关阅读:
    冲刺二4
    第十四周总结
    大道至简阅读笔记02
    冲刺二3
    冲刺二2
    大道至简阅读笔记01
    冲刺二1
    第十三周总结
    第一阶段意见评价
    5月23日团队开发日志
  • 原文地址:https://www.cnblogs.com/ttzz/p/13974708.html
Copyright © 2011-2022 走看看