例如, 1~13 中包含 1 的数字有 1 、 10 、 11 、 12 、 13 因此共出现 6 次
  注意:11 这种情况算两次 
   数据范围: 
 
   进阶:空间复杂度 %20%5C) ,时间复杂度
 ,时间复杂度 %20%5C)
 
                                         咩咩jiang
                                            咩咩jiang
                                        class Solution {
public:
    /*
    	我们从低位到高位求每位1出现的次数,累加求和即可
        例如:求0~abcde中1的个数,现在我们求c这一位中1出现的次数,其他位雷同
        有两部分组成
        第一部分:ab * 100,表示当ab这两位在0~ab-1范围内时,de可以从0~99取值
    	    第二部分:如果c>1时,当ab为ab时1的个数为0~99
                  如果c=1时,当ab为ab时1的个数为de + 1
                如果c<0时,当ab为ab是1的个数为0
    */
    int NumberOf1Between1AndN_Solution(int n)
    {
        int exp = 1;
        int ans = 0; 
        while(n / exp)
        {
        	ans += n / (exp * 10) * exp;
            if(n % (exp * 10) / exp  > 1) ans += exp;
            else if(n % (exp * 10) / exp == 1) ans += (n % exp + 1);
            exp *= 10;
        }
        return ans;
    }
};
                                                                                    def countDigitOne(self, n):
        """
        :type n: int
        :rtype: int
        例:对于824883294,先求0-800000000之间(不包括800000000)的,再求0-24883294之间的。
        如果等于1,如1244444,先求0-1000000之间,再求1000000-1244444,那么只需要加上244444+1,再求0-244444之间的1
        如果大于1,例:0-800000000之间1的个数为8个100000000的1的个数加上100000000,因为从1000000000-200000000共有1000000000个数且最高位都为1。
        对于最后一位数,如果大于1,直接加上1即可。
        """
        result = 0
        if n < 0:
            return 0
        length = len(str(n))
        listN = list(str(n))
        for i, v in enumerate(listN):
            a = length - i - 1  # a为10的幂
            if i==length-1 and int(v)>=1:
                result+=1
                break
            if int(v) > 1:
                result += int(10 ** a * a / 10) * int(v) + 10**a
            if int(v) == 1:
                result += (int(10 ** a * a / 10) + int("".join(listN[i+1:])) + 1)
        return result
最怕遇到这种有逻辑,得小心翼翼的题目了
class Solution {
public:
    int NumberOf1Between1AndN_Solution(int n)
    {
        //统计每一位上1出现的次数
        int ret = 0, base = 1;
        while (n/base) {
            int bit = (n / base) - (n / base) / 10 * 10;
            if (bit == 0)
                ret += n / (base * 10)*base;
            if (bit == 1)
                ret += n / (base * 10)*base + (n - n/base*base ) + 1;
            if (bit > 1)
                ret += (n / (base * 10) + 1)*base;
            base *= 10;
        }
        return ret;
    }
}; public class Solution {
  public int NumberOf1Between1AndN_Solution(int n) {
	    if(n<0){
	    	return 0;
	    }
	    String str= Integer.toString(n);
	    int result = getNumberOf1(str, 0);
	    return result;
    }
	public static int getNumberOf1(String str,int index){
		int length = str.length()-index;
		if(length==1 && str.charAt(index)=='0'){
			return 0;
		}
		if(length==1){
			return 1;
		}
		//计算最高位的1
		int first = str.charAt(index)-'0';
		int result = 0;
		if(first>1){
			result += exp(length-1); 
		}else if(first==1){
			result += 1 + Integer.parseInt(str.substring(index+1));
		}
		//计算除了最高位的其他位
		result += first *(length-1)*exp(length-2);
		//计算比如2345中0---345中1的个数进行递归
		result += getNumberOf1(str, index+1);
		
		return result;
	}
	public static int exp(int n){
		int result =1;
		while(n>=1){
			result*=10;
			n--;
		}
		return result;
	}
}
看了一圈似乎都是在数字本身上纠结的,我这个算是另辟奇径,就是把数字先转换为字符串,再连接起来,再数1出现的次数
class Solution:
    def NumberOf1Between1AndN_Solution(self, n):
        # write code here
        str_n = ''
        for i in range(1, n + 1):
            str_n += str(i)
        res = str_n.count('1')
        return res
                                                                                    public class Solution {
    public int NumberOf1Between1AndN_Solution(int n) {
        //count表示1出现的总次数
		int count = 0;
		//从1到n循环n次,对每一个数求它包含多少个1
		for (int i = 1; i <= n; i++) {
			int temp = i;
			//求这个数包含多少个1
			while (temp != 0) {
				if (temp % 10 == 1) {
					count++;
				}
				temp = temp / 10;
			}
		}
		return count;
    }
}
  思路来自B站视频。以下是原链接
 https://www.bilibili.com/video/BV1uJ411573j?t=1824
 假设n = 7543 [x] 29
 如果要让百位的x = 1,那么需要考虑以下几种情况: 
class Solution: def NumberOf1Between1AndN_Solution(self, n): # 运行时间:31ms 占用内存:5860k m = len(str(n)) # 数字的长度 count = 0 for i in range(1, m+1): high = n // 10 ** i # 找到当前位之前的位数 mid = n % 10 ** i // 10 ** (i - 1) # 找当前位 low = n % 10 ** (i - 1) # 找当前位后面的位数 # 第(1)个情况 count += high * (10 ** (i - 1)) if mid > 1: # 第(2.1)个情况 count += 10 ** (i - 1) elif mid == 1: # 第(2.2)个情况 count += (low + 1) return count
    # 利用组合数解题
    # 依次遍历每一个数位,计算该位为1的数有多少个,将结果累加返回
    # 每个数位计算的时候,对除去该位的前缀,后缀分别计算组合数
    # 同时需要保证组合出的数字在n的范围之内,所以将情况分为三种,该数位原本为1或者为0,或者为其他
    def NumberOf1Between1AndN_Solution(self, n):
        # write code here
        if n == 1:  # 边界情况
            return 1
        ans = 0  # 最后返回的1的个数
        x = str(n)  # n的字符串形式,便于前缀后缀的数字转换
        for i in range(len(x)):  # 遍历每一个数位,计算该数位为1同时整个数在n之内的整数个数
            pre = int(x[:i]) if x[:i] else 0  # 前缀,没有前缀为0
            l = len(x[i + 1:])  # 后缀的长度
            # 该位原本为0的时候,合法数的前缀必小于pre,范围为[0,pre),共有pre种,后缀任意均合法,共有10**l种
            if x[i] == '0':
                ans += pre * 10 ** l
            # 该位原本为1的时候,合法数有两种
            # 一种是前缀范围为[0,pre),共有pre种,后缀任意
            # 另一种是前缀为pre,后缀范围[0,suf],共suf+1种
            elif x[i] == '1':
                suf = int(x[i+1:]) if x[i+1:] else -1  # 后缀范围,没有后缀为-1
                ans += pre * 10 ** l + suf + 1
            # 其他情况下,合法数前缀范围[0,pre],后缀任意
            else:
                ans += (pre+1) * 10 ** l
        return ans
                                                                                    function NumberOf1Between1AndN_Solution(n)
{    var count=0;
     var j=0;
     var sum=0;
    for(var i=1;i<=n;i++){
        var kk=i.toString();
        j=0;
        count=0;
        while(kk.indexOf(1,j)!==-1){
                count++;
                j=kk.indexOf(1,j)+1;
            }
        
        sum+=count;
    }
 return sum;
}
 数字转换成字符串,匹配字符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,一共114个,等于低位数字(113)+1。 ③ 如果百位上数字大于1(2~9),则百位上出现1的情况仅由更高位决定,比如12213,则百位出现1的情况是:100~199,1100~1199,2100~2199,...,11100~11199,12100~12199,一共有1300个,并且等于更高位数字+1(12+1)乘以当前位数(100)。 */ public class Solution { public int NumberOf1Between1AndN_Solution(int n) { int count = 0;//1的个数 int i = 1;//当前位 int current = 0,after = 0,before = 0; while((n/i)!= 0){ current = (n/i)%10; //高位数字 before = n/(i*10); //当前位数字 after = n-(n/i)*i; //低位数字 //如果为0,出现1的次数由高位决定,等于高位数字 * 当前位数 if (current == 0) count += before*i; //如果为1,出现1的次数由高位和低位决定,高位*当前位+低位+1 else if(current == 1) count += before * i + after + 1; //如果大于1,出现1的次数由高位决定,//(高位数字+1)* 当前位数 else{ count += (before + 1) * i; } //前移一位 i = i*10; } return count; } }
    public int NumberOf1Between1AndN_Solution(int n) {
        if(n<10)return n>=1?1:0;
        int times=(int)(Math.pow(10,String.valueOf(n).length()-1));
        int a=Integer.parseInt(String.valueOf(n).substring(0,1));
        int b=Integer.parseInt(String.valueOf(n).substring(1,String.valueOf(n).length()));
        return a>1?times+a*NumberOf1Between1AndN_Solution(times-1)+NumberOf1Between1AndN_Solution(b):
                b+1+NumberOf1Between1AndN_Solution(times-1)+NumberOf1Between1AndN_Solution(b);
    }
     public int NumberOf1Between1AndN_Solution(int n) {
        int times = 0,current, addOne = 0,powerOfTen = 0,n2 = n;
        while (n > 0){
            current = n % 10;
            n /= 10;
            if (current > 1) {
                addOne = 1;
            }
            else if (current == 1){
                times += (n2 % Math.pow(10,powerOfTen)) + 1;
            }
            times += (n + addOne) * Math.pow(10, powerOfTen);
            powerOfTen++;
            addOne = 0;
        }
        return times;
    }
class Solution {
public:
    // 计算从0到n中1的总数
    int NumberOf1Between1AndN_Solution(int n)
    {
        int count = 0;
    	for(int i=0;i<=n;i++) {
            count += NumberOf1(i);
        }
        return count;
    }
    // 计算数字n中1的个数
    int NumberOf1(int n)
    {
        int count = 0;
        while(n) {
            if(n%10 == 1) count++;
            n /= 10;
        }
        return count;
    }
};