Nième chiffre - Problème Leetcode 400

Dec 10 2022
Lien du problème d'origine : https://leetcode.com/problems/nth-digit/description/ Dans ce problème, on nous demande de trouver le nième chiffre de la séquence infinie écrite sous la forme d'une chaîne 1,2,3,4,5 ,6,7,8,9… Par exemple, le 3e chiffre serait 3, mais le 10e chiffre serait 1 (la place des dizaines de 10) et le 11e serait 0 (la place des unités de 10).

Lien du problème d'origine :https://leetcode.com/problems/nth-digit/description/

Dans ce problème, on nous demande de trouver le nième chiffre de la suite infinie écrite sous la forme d'une chaîne 1,2,3,4,5,6,7,8,9…

Par exemple, le 3e chiffre serait 3, mais le 10e chiffre serait 1 (la place des dizaines de 10) et le 11e serait 0 (la place des unités de 10).

Avant d'en venir aux explications, l'approche rapide qui bat 100 % des soumissions est la suivante, mais nous devons utiliser un peu de mathématiques :

class Solution {
    public int findNthDigit(int n) {
        if (n < 10) {
            return n;
        }
        long numOfDigits = 0;
        long power = 1;
        while (numOfDigits + (9 * (long)Math.pow(10, power - 1) * power) <= n) {
            numOfDigits += (9 * (long)Math.pow(10, power - 1) * power);
            power++;
        }
        long quotient = (n - numOfDigits) / power;
        long mod = (n - numOfDigits) % power;
        long i = mod == 0 ? (quotient + (long)Math.pow(10, power - 1) - 1) : (quotient + (long)Math.pow(10, power - 1));
        String num = String.valueOf(i);
        return mod == 0 ? Character.digit(num.charAt(num.length() - 1), 10) : Character.digit(num.charAt((int)mod - 1), 10);
    }
}

J'ai donc changé pour parcourir et calculer le nombre correct à partir duquel le nième chiffre serait, comme ceci:

class Solution {
    public int findNthDigit(int n) {
        int i = 0;
        int prevIndex = 0;
        int index = 0;
        while (index < n) {
            i++;
            String num = String.valueOf(i);
            prevIndex = index;
            index += num.length();
        }
        String str = String.valueOf(i);
        return Character.digit(str.charAt(n - prevIndex - 1), 10);
    }
}

Le moyen de le rendre plus rapide et de le faire accepter était de rendre la solution O (log n) en trouvant un modèle pour le nombre de chiffres générés par chaque plage de nombres, comme suit

Single digits 1-9 => 9 * 10^0 * 1 digits
Double digits 10-99 => 9 * 10^1 * 2 digits
...so the general formula is 9 * 10^(m - 1) * m digits for each number range

class Solution {
    public int findNthDigit(int n) {
        if (n < 10) {
            return n;
        }
        long numOfDigits = 0;
        long power = 1;
        while (numOfDigits + (9 * (long)Math.pow(10, power - 1) * power) <= n) {
            numOfDigits += (9 * (long)Math.pow(10, power - 1) * power);
            power++;
        }
        long quotient = (n - numOfDigits) / power;
        long mod = (n - numOfDigits) % power;
        long i = mod == 0 ? (quotient + (long)Math.pow(10, power - 1) - 1) : (quotient + (long)Math.pow(10, power - 1));
        String num = String.valueOf(i);
        return mod == 0 ? Character.digit(num.charAt(num.length() - 1), 10) : Character.digit(num.charAt((int)mod - 1), 10);
    }
}