剑指offer上的递归解法确实难以理解且不是最佳解法,下面这个博客巧妙地找规律。
https://blog.csdn.net/yi_afly/article/details/52012593
思路是求出数字每一位出现1的次数,最后求和。
每一位出现的次数和前面后面的数字都有关系,和前面的关系是 必定出现了 当前位权重*前面的数字次 ,和后面的关系分三种情况
1. 当前位是0,也就是后面的不再增加当前位出现1的次数
2. 当前位是1,后面的数字是多少,在当前位1就出现多少次
3. 当前位大于1,直接就是出现了当前位的权重次
权重就是指个位1,十位10,百位100
#include <stdio.h>
int NumberOf1Between1AndN_Solution(int n)
{
//weight当前位权重,round当前位之前的数字,count 1的总次数
int weight = 1;
int round = n;
int count = 0;
while (round > 0) {
int cur = round % 10;
round /= 10;
count += round * weight;
if(cur == 1){
count += (n%weight) + 1;
}
if (cur > 1) {
count += weight;
}
weight *= 10;
}
return count;
}
int main()
{
int ret = NumberOf1Between1AndN_Solution(5678);
}