例如輸入12 ,從1 到12 這些整數中包含1 的數字有1、10、11 和12,1 一共出現了5 次。
第一種:不誇慮時間效率的解法
累加1 到n 中每個整數1 出現的次數。我們可以每次通過對10 求餘數判斷整數的個位數字是不是1 。如果這個數字大於10,除以10 之後再判斷個位數字是不是1 。
第二種:從數字規律著手明顯提高時間效率的解法
21345 作為例子來分析。我們把從1 到21345 的所有數字分為兩段, 一段是從1 到1345,另一段是從1346 到21345。
我們先看從1346 到21345 中1 出現的次數。1 的出現分為兩種情況。首先分析1出現在最高位(本例中是萬位)的情況。從1346 到21345 的數字中, 1出現在10000~19999 這10000 個數字的萬位中, 一共出現了10000(10^4)個。
值得注意的是, 並不是對所有5 位數而言在萬位出現的次數都是10000
個。對於萬位是1 的數字比如輸入12345, 1 只出現在10000~ 12345 的萬位,出現的次數不是10^4 次,而是2346 次,也就是除去最高數字之後剩下的數字再加上1 (即2345+1=2346 次)。
接下來分析1出現在除最高位之外的其他四位數中的情況。例子中1346~21345 這20000 個數字中後4 位中1 出現的次數是2000 次。由於最
高位是2,我們可以再把1346~21345 分成兩段, 1346~11345 和1 1346~21345 。每一段剩下的4 位數字中, 選擇其中一位是1 ,其餘三位可以在0~9 這10 個數字中任意選擇,因此根據排列組合原則,總共出現的次數是2*4*10^3=8000
至於從l 到1345 中1 出現的次數,我們就可以用遞迴求得了。這也是我們為什麼要把1~21345 分成1~ 1 345 和1346~21345 兩段的原因。因為把21345 的最高位去掉就變成1345 ,便於我們採用遞迴的思路,這樣下次遞迴的時候就可以捨棄最高位2,直接衝1開始了。
採用第二種思路:也就是分拆遞迴的思路。
package 劍指offer;
/*題目:輸入乙個整數n求從1 到n這n個整數的十進位制表示中1 出現的次數。
例如輸入12 ,從1 到12 這些整數中包含1 的數字有1、10、11 和12,1 一共出現了5 次。
*/public class test32
return numberof1(number, 0); }
// 判斷字元陣列number從currentid位置開始包含1的個數
public static int numberof1(int number, int currentid)
int length = number.length - currentid;
// 記錄第乙個位置的也就是數字最高位的元素
int first = number[currentid];
// 用於記錄最高位包含1時的總數
int numfirst = 0;
if (length == 1 && first == 0)
// 如果只有一位且這一位不是0返回1
if (length == 1 && first > 0)
if(first == 1)else if(first > 1)
// numother是[1346, 21345]中,除了第一位之外(不看21345中的第一位2)的數字中的1的數目
int numother = first * (length - 1) * powerbase10(length - 2);
// numrecur是1-1234中1的的數目,這個使用迭代的方式來實現
int numrecur = numberof1(number, currentid + 1);
return numfirst + numother + numrecur; }
public static int powerbase10(int n)
return result;
}private static int atoi(int numbers, int i)
return result;
} public static void main(string args)
}
收穫:1、string value = num + 「」;可以將整形轉化成字串
2、num = char - 『0』;的方式可以將char轉換成數字,其依據是acsii碼表轉換
3、加深理解遞迴的思想。
劍指Offer (29)最小的k個數
題目描述 輸入n個整數,找出其中最小的k個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4。實現如下 測試用例中給出的返回值是有序的。嘖嘖。找到序列中最小的k個數,利用set,對數字進行insert或erase 紅黑樹中查詢 插入 刪除操作都為 o logk 最...
劍指offer 29 最小的K個數
題目 輸入n個整數,找出其中最小的k個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4,思路分析 簡單思路 先快排,再取數 coding utf 8 class solution def getleastnumbers solution self,tinput,...
劍指offer 29 最小的K個數
輸入n個整數,找出其中最小的k個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4。最簡單容易想到的就是先排序,然後輸出前k個數即可。但是這樣明顯時間複雜度比較高。也可以使用另外的方法,具體不再詳述。class solution for int i 0 i inp...