The problem asks to find the nth number in a sequence where numbers containing the digit '9' are removed. A brute-force approach would be inefficient for large values of n
. Instead, we can use a mathematical approach to efficiently determine the nth number.
Core Idea:
The key observation is that the sequence without '9's can be mapped to a base-9 system. Each digit in the base-9 representation corresponds to a digit in the modified sequence (0 maps to 0, 1 maps to 1, ..., 8 maps to 8). Converting n
to base 9 effectively gives us the digits of the result in the modified sequence. However, we must adjust since base 9 starts from 0, while we need 1-based indexing.
Algorithm:
Convert n to base 9: Convert the input n
to its base 9 representation. We subtract 1 from n
before conversion because our sequence is 1-indexed, while base-9 representation is 0-indexed.
Construct the result: Iterate through the base 9 digits. Each digit represents a digit in the final answer. However, since we skipped numbers with '9', we replace any instance of 0, 1, 2, ..., 7 with the same digit. This mapping directly from base 9 to the sequence of numbers without 9s.
Return the result: The constructed number is the nth number in the modified sequence.
Time Complexity Analysis:
The dominant operation is converting n
to base 9. The number of digits in the base 9 representation of n
is proportional to log9(n). Each digit conversion takes constant time. Therefore, the overall time complexity is O(log9n), which is effectively O(log n).
Space Complexity Analysis:
The space complexity is O(log n) because we need to store the base 9 digits, the number of which is proportional to log9(n).
Code Implementation (Python):
def newInteger(n: int) -> int:
"""
Finds the nth integer in the sequence without numbers containing '9'.
Args:
n: The index of the desired integer (1-indexed).
Returns:
The nth integer in the modified sequence.
"""
n -= 1 # Adjust for 0-based indexing in base 9 conversion
base9_digits = []
while n > 0:
digit = n % 9
base9_digits.insert(0, digit) # Prepend for correct order
n //= 9
result = 0
for digit in base9_digits:
result = result * 10 + digit
return result
Code Implementation (Java):
class Solution {
public int newInteger(int n) {
n--; // Adjust for 0-based indexing
List<Integer> base9Digits = new ArrayList<>();
while (n > 0) {
int digit = n % 9;
base9Digits.add(0, digit); // Prepend for correct order
n /= 9;
}
int result = 0;
for (int digit : base9Digits) {
result = result * 10 + digit;
}
return result;
}
}
Code Implementation (C++):
class Solution {
public:
int newInteger(int n) {
n--; // Adjust for 0-based indexing
vector<int> base9Digits;
while (n > 0) {
int digit = n % 9;
base9Digits.insert(base9Digits.begin(), digit); // Prepend for correct order
n /= 9;
}
int result = 0;
for (int digit : base9Digits) {
result = result * 10 + digit;
}
return result;
}
};
Code Implementation (Go):
func newInteger(n int) int {
n-- // Adjust for 0-based indexing
base9Digits := []int{}
for n > 0 {
digit := n % 9
base9Digits = append([]int{digit}, base9Digits...) // Prepend for correct order
n /= 9
}
result := 0
for _, digit := range base9Digits {
result = result*10 + digit
}
return result
}
These implementations all follow the same algorithm, achieving the optimal time and space complexity. Remember to choose the implementation that best suits your preferred programming language.