1. 程式人生 > >LeetCode演算法題-Nth Digit(Java實現)

LeetCode演算法題-Nth Digit(Java實現)

這是悅樂書的第215次更新,第228篇原創

01 看題和準備

今天介紹的是LeetCode演算法題中Easy級別的第83題(順位題號是400)。找到無限整數序列的第n個數字1,2,3,4,5,6,7,8,9,10,11 ......例如:

輸入:3
輸出:3

輸入:11
輸出:0
說明:序列1,2,3,4,5,6,7,8,9,10,11 ......的第11位是0,它是數字10的一部分。

注意:n為正整數且符合32位有符號整數(n <2^31)的範圍。

本次解題使用的開發工具是eclipse,jdk使用的版本是1.8,環境是win7 64位系統,使用Java語言編寫和測試。

02 第一種解法

直接使用for迴圈,從1開始累加字串,返回第n-1個字元所表示的整數即可。但是此方法嚴重超時,不建議使用

public int findNthDigit(int n) {
    String str = "";
    for (int i=1; i<= n; i++) {
        str += i;
    }
    return Integer.parseInt(str.charAt(n-1)+"");
}


03 第二種解法

題目的意思是有一個以正整數(1,2,3,4,依次向後加1)為基礎組成的序列(也可以理解為字串),傳入一個整數n,找出在該序列中的第n位數字。該序列含有以下規律:

  • 1-9,有9個一位數,當n小於等於9的時候,可以在裡面找到值。

  • 10-99,有90個兩位數,當n大於9且小於等於180+9=189時,可以在裡面找到值。

  • 100-999,有900個三位數,當n大於189且小於900x3+189=2889時,可以在裡面找到值。

我們可以將此問題分解為三個步驟:

  • 先計算該數字的位數,確定範圍。

  • 找出該數字。

  • 確定是該數字中的第幾位數。

例如:303

第一步,因為189<303<2889,所以我們要找的是一個三位數,303-189=114,此時n變成114。

第二步,我們要找的數變成了三位數中的第114位,那我們就可以計算出三位數中的第114位數是100+(114-1)/3=137。這裡減1是因為在字串中,索引是從0開始的,而我們的序列字串是從1開始,所以要減1,你也可以從一開始就減1。

第三步,計算是137中的第幾位數,(114-1)%3=2,也就是137的第2位(從0開始)數7,就是我們想要的結果。

在程式碼中我們使用long型別,預防溢位的風險。

public int findNthDigit2(int n) {
    long start = 1, count = 1, num = 9;
    while (n > num*count) {
        n -= num*count;
        count += 1;
        start *= 10;
        num *= 10;
    }
    start += (n-1)/count;
    String result = start+"";
    long index = (n-1)%count;
    return result.charAt((int)index)-'0';
}


04 小結

演算法專題目前已連續日更超過兩個月,演算法題文章83+篇,公眾號對話方塊回覆【資料結構與演算法】、【演算法】、【資料結構】中的任一關鍵詞,獲取系列文章合集。

以上就是全部內容,如果大家有什麼好的解法思路、建議或者其他問題,可以下方留言交流,點贊、留言、轉發就是對我最大的回報和支援!