一緒に書く習慣をつけましょう!「ナゲッツデイリーニュープラン・4月アップデートチャレンジ」に参加して7日目です。クリックしてイベントの詳細をご覧ください。
1.問題の説明
整数 を指定して、以下のすべて の非負の整数 の出現回数をn
カウント します。n
1
トピックリンク:番号1の数
第二に、主題の要件
例1
输入: n = 13
输出: 6
复制代码
例2
输入: n = 0
输出: 0
复制代码
訪問
1.数学思想、超时优化
2.建议用时15~35min
复制代码
3.問題分析
この質問を手にした途端、何かがおかしいと感じました。ループで数えるだけの非常に単純な質問でしたが、Likouは実際に難しいラベルを付けました。
class Solution {
public:
int countDigitOne(int n) {
int i,k,ans=0;//初始化数据
for(i=1;i<=n;i++)//循环1~n
{
k=i;
while(k)//数位中是否包含1
{
if(k%10==1)
ans++;//计数
k=k/10;
}
}
return ans;//输出结果
}
};
复制代码
だから、私のコードは間違いなくタイムアウトします。
解決策>_<を読んだ後、これは通常の質問であることがわかりました。
ルールは次のとおりで、大物のアイデアを利用しています。
/**
从低往高位,计算每一位的数量:
第1位上的1的个数:1+(n-1)/10
第2位上的1的个数:(1+(n/10-1)/10)*10
第3位上的1的个数:(1+(n/100-1)/10)*100
……
第k+1位上的1的个数:(1+(n/(10^k)-1)/10)*(10^k)
如果n的第k+1位上是1,则说明可能没有填满该位,计算第k+1位的数量时还要 -10^k+1+n%(10^k),相当于独立计算
*/
复制代码
第四に、エンコーディングの実装
class Solution {
public:
int countDigitOne(int n) {
long long k = 1,ans = 0;//初始化数据
while (n >= k){
ans += (1+(n/k-1)/10)*k;//计数
if (n/k%10 == 1) ans = ans-k+1+n%k;//当前位为1,减去数据
k *= 10;
}
return ans;//输出结果
}
};
复制代码