演算法-找出1出現的個數
阿新 • • 發佈:2020-12-09
從1到n整數中1出現的次數
題目:獲取從1到n整數中1出現的次數,如n=13,則1,10,11,12,13中出現1的次數總共為6,則返回6
一、暴力求解
//遍歷每個數字的每個位
public class Solution {
public int NumberOf1Between1AndN_Solution(int n) {
int count = 0;
for(int i = n; i >= 1; i--) {
for(int j = i; j > 0; j /= 10) {
if (j % 10 == 1) {
count++;
}
}
}
return count;
}
}
方法二:遞迴方法(參考力扣答案)
思路:
f(n)為1-n範圍內,這n個數中1出現的次數
首先將n分為兩種情況:情況一:最高位為1(如1234);情況二:最高位不為1(如3234)
情況一:當最高位為1時(以1234為例):
①:將n分為兩部分,最高位單獨拿出來為1,定義為high;剩下的部分為234,定義為last;
②:獲取到最高位的分位,為千分位,即定義pow=1000;
1.1-999範圍內,1的個數為f(pow-1);
2.1000-1234範圍內:
1)首先只考慮千分位是1的個數:也就是1000、1001、1002…1234,即234+1,轉換下為:last+1
2)其次考慮其他位數上的1的個數為:f(last)。
綜上所述:情況一中1出現的次數為:f(pow-1)+last+1+f(last)
情況二:當最高為不為1時(以3234為例):
①:1-999範圍內,1的個數依然為:f(pow-1);
②:1000-1999範圍內:
1)只考慮千分位是1的個數為:1000、1001、1002…1999即1000個也就是pow;
2)其他位數上1的數量為:f(pow-1)
③:2000-2999範圍內1的個數:f(pow-1),注意這裡的千分位是2,所以不要考慮分兩種情況
綜上所述:情況二中1出現的次數為:pow+high*f(pow-1)+f(last);
public int NumberOf1Between1AndN_Solution(int n){
//base case
if(n<1){
return 0;
}
if(n<10){
return 1;
}
String s=String.valueOf(n);
int high=s.charAt(0)-'0';
int pow=(int)Math.pow(10,s.length()-1);
int last=n-high*pow;
if(high==1){
return NumberOf1Between1AndN_Solution(pow-1)+last+1+NumberOf1Between1AndN_Solution(last);
}else{
return pow+high*NumberOf1Between1AndN_Solution(pow-1)+NumberOf1Between1AndN_Solution(last);
}
}