本文參考自《劍指offer》一書,代碼采用Java語言。
題目
數字以0123456789101112131415…的格式序列化到一個字符序列中。在這個序列中,第5位(從0開始計數)是5,第13位是1,第19位是4,等等。請寫一個函數求任意位對應的數字。
思路
逐一枚舉數字,計算每個數字的位數相加,效率太低。
觀察規律:
個位數的個數一共有10個,即0~9,共占了10*1位數字;
兩位數的個數一共有90個,即10~99,每個數字占兩位,共占了90*2位數字;
……
m位數的個數一共有9*10^(m-1)個,每個數字占m位,占了9*10^(m-1)*m位數字。
判斷第n個對的數字是屬於幾位數,再從幾位數中進行尋找。
測試算例
1.功能測試(輸入19、1000等)
2.邊界值測試(輸入0、1等)
Java代碼
//題目:數字以0123456789101112131415…的格式序列化到一個字符序列中。在這
//個序列中,第5位(從0開始計數)是5,第13位是1,第19位是4,等等。請寫一
//個函數求任意位對應的數字。
public class DigitsInSequenc {
public int digitAtIndex(int index) {
if(index<0)
return -1;
int m=1; //m位數
while(true) {
int numbers=numbersOfIntegers(m); //m位數的個數
if(index<numbers*m)
return getDigit(index,m);
index-=numbers*m;
m++;
}
}
/*
* 返回m位數的總個數
* 例如,兩位數一共有90個:10~99;三位數有900個:100~999
*/
private int numbersOfIntegers(int m) {
if(m==1)
return 10;
return (int) (9*Math.pow(10, m-1));
}
/*
* 獲取數字
*/
private int getDigit(int index, int m) {
int number=getFirstNumber(m)+index/m; //對應的m位數
int indexFromRight = m-index%m; //在數字中的位置
for(int i=1;i<indexFromRight;i++)
number/=10;
return number%10;
}
/*
* 第一個m位數
* 例如第一個兩位數是10,第一個三位數是100
*/
private int getFirstNumber(int m) {
if(m==1)
return 0;
return (int) Math.pow(10, m-1);
}
public static void main(String[] args) {
DigitsInSequenc demo=new DigitsInSequenc();
System.out.println(demo.digitAtIndex(0)==0);
System.out.println(demo.digitAtIndex(1)==1);
System.out.println(demo.digitAtIndex(19)==4);
System.out.println(demo.digitAtIndex(1000)==3);
System.out.println(demo.digitAtIndex(1001)==7);
System.out.println(demo.digitAtIndex(1002)==0);
}
}
收獲
1.程序邏輯要整理清楚,細節要注意
