(悪いな、質問をするのが本当に遅い。このインタビューでこの質問をされたら、私は愚かだと思う)
問題:
整数 n が与えられたとき、n 以下のすべての非負の整数に含まれる数値 1 の出現回数を数えます。
解決策:
最初に整数の範囲を調べます 0 <= n <= 10^9 はトラバースできません (ただし、これは確かにトラバースが容易ではありません)
たとえば、25103 という数字がありますが、どこから始めればよいでしょうか。
各位置に 1 がある場合の数 (1、10 など) を考慮し、それらを合計して結果を取得できますか?
まず一般的な状況を考えてみましょう, 数 xxx 4 yy, 百の位で, 1 があるケースの数を計算する方法?
100, 101, 102, ..., 199 が百の位ですべて 1 であるかどうかを考えてみましょう.この場合、100件
を検討中です 百の前のxxxをチェックすると、全部で(xxx+1)×100種類
(xxxを123とすると、123の100種類あるとします) 1 yy, 100 122 1 yy の種類... 000 1 yy の 100 種類)
次に、一般的な状況を少し拡張しましょう. 数 xxxx は 4 y 十桁は (xxxx + 1) * 10 と同じですか?
次に、特殊なケースを考えます. xxx 1 yy の百の位が 1 の場合、これはどのように数えるでしょうか?
前が xxx の場合、百の位が 1 の場合は yy しかありませんが、前が ( xxx-n)、状況 100種類ある
ので、xxx*100+yy種類
?
別の特殊なケースで、xxx 0 yy という数字が百の位が 0 の場合、どのように計算するのでしょうか?
実は、その前の xxx の場合、百の位が 1 の場合は 0 です。 xxx - n) の前に、 100 のケースもあります
ので、ケースは xxx * 100 です
次にコードを書くだけです
class Solution {
public:
int countDigitOne(int n) {
int res = 0;
int f = 1;
int nn = n / 10;
while(nn != 0) {
nn = nn / 10;
f = f * 10;
}
int flag = 0;
while(f != 0) {
int t = n / f;
n = n % f;
if(t == 1) {
res = res + n + 1 + flag * f;
}
else if(t == 0) {
res = res + flag * f;
}
else {
res = res + (flag + 1) * f;
}
flag = flag * 10 + t;
f = f / 10;
}
return res;
}
};