腾讯面试题 (算法)从0到n整数中数字7出现的次数
思路:
1、暴力方法,数出每个数字包含几个7,然后累加起来。
2、分析:分别考虑数字n每一位出现7的次数,如4579843;
从左往右考虑 4579843;
考虑 5(即第6位):
5<7, 故第7位(5的高位部分)取到(0-3时)5后面的低位部分可以随便取 10^5种情况;
因此该位出现7的次数为 4 * 10^6/10
考虑 7(即第5位):
7固定,当7的高位去 (0-44)时,7的低位随便取10^4;
当7的高位等于45时,7的低位为(0-9843)共9843+1种情况;
所以7出现的次数为 45*10^5/10 + 9843 + 1
考虑 9(即第4位):
9>7;当9的高位取到(0-457)时,第4位取7时,低位共 10^3种情况;
所以:该位出现7的次数为 (457+1)* 10^3;
附:除以10的原因在于:每10个数字,任意位出现7的概率为1/10.
总结规律:
第i位出现7个次数与该位所在的数字有关:
当第i位的数字 <7:
出现次数就= 比其高位部分的数字 * 10^i/10;
当第i位的数字=7:
出现次数就= 比其高位部分的数字 * 10^i/10 + n%(10^i/10) + 1;
当第i位的数字>7:
出现次数就=(比其高位部分的数字+1)* 10^i/10;
具体代码
#include<iostream>
#include<math.h>
#include<string>
using namespace std;
int count7(int number, int d) {
int pownum = pow(10, d);
int gaowei = number / (pownum * 10); //比当前位高的位
int digit = (number / pownum) % 10; //当前位的数字
if (digit < 7) {
return gaowei * pownum;
}else if (digit == 7) {
return gaowei * pownum + number % pownum + 1;
}else {
return (gaowei + 1) * pownum;
}
}
int main() {
int number;
cin >> number;
int count = 0;
string str;
str = to_string(number);
//从第0位开始到最高位
for (int i = 0; i < str.size(); i++) {
count += count7(number, i);
}
cout << count<< endl;
return 0;
}
LeetCode同类型的题目:
[https://leetcode-cn.com/problems/number-of-2s-in-range-lcci/]