From 9dba4b523f7f6b81a634c75b2a49bd1ab82241c0 Mon Sep 17 00:00:00 2001 From: tofes Date: Thu, 26 Jun 2025 13:35:52 -0700 Subject: [PATCH] Update Uniform_Integers.py More efficient solution. --- Level 1/Uniform_Integers.py | 87 ++++++++----------------------------- 1 file changed, 18 insertions(+), 69 deletions(-) diff --git a/Level 1/Uniform_Integers.py b/Level 1/Uniform_Integers.py index b0251a9..1ec958c 100644 --- a/Level 1/Uniform_Integers.py +++ b/Level 1/Uniform_Integers.py @@ -9,76 +9,25 @@ ## 1 <= A <= B <= 10^(12) ## Solution -## Time Complexity: O(log10(A * B)) == O(log10(A) + log10(B)) -## Space Complexity: O(log10(A * B)) -## Explanation: Given an uniform integer D, we can determine how many uniform -## integers are less than or equal to D in O(log10(D)) time. So to find the -## number of uniform integers between A and B, we just need to subtract the -## number of uniform integers less than B from the number of uniform integers -## less than A. To find the smallest uniform integer greater than A, we -## need to do is make a uniform integer by changing all of A's digits to A's -## first digit. For example, 2468753 becomes 2222222. If it is smaller than A -## then the next uniform integer will be greater than A. This takes O(log10(A)) -## time for A and O(log10(B)) for B, resulting in O(log10(A) + log10(B)) time. - -## Here's the pattern: -## 0 * 9 + 1 -> 1 | 1 * 9 + 1 -> 11 | 2 * 9 + 1 -> 111 | 3 * 9 + 1 -> 1111 -## 0 * 9 + 2 -> 2 | 1 * 9 + 2 -> 22 | 2 * 9 + 2 -> 222 | 3 * 9 + 2 -> 2222 -## 0 * 9 + 3 -> 3 | 1 * 9 + 3 -> 33 | 2 * 9 + 3 -> 333 | 3 * 9 + 3 -> 3333 -## 0 * 9 + 4 -> 4 | 1 * 9 + 4 -> 44 | 2 * 9 + 4 -> 444 | 3 * 9 + 4 -> 4444 -## 0 * 9 + 5 -> 5 | 1 * 9 + 5 -> 55 | 2 * 9 + 5 -> 555 | 3 * 9 + 5 -> 5555 -## 0 * 9 + 6 -> 6 | 1 * 9 + 6 -> 66 | 2 * 9 + 6 -> 666 | 3 * 9 + 6 -> 6666 -## 0 * 9 + 7 -> 7 | 1 * 9 + 7 -> 77 | 2 * 9 + 7 -> 777 | 3 * 9 + 7 -> 7777 -## 0 * 9 + 8 -> 8 | 1 * 9 + 8 -> 88 | 2 * 9 + 8 -> 888 | 3 * 9 + 8 -> 8888 -## 0 * 9 + 9 -> 9 | 1 * 9 + 9 -> 99 | 2 * 9 + 9 -> 999 | 3 * 9 + 9 -> 9999 - +## Time Complexity: O(9 * log10(B)) +## Space Complexity: O(1) +## Explanation: +''' + n = [1..9] + v0 = 0 + 1 = 1 + 0 + 0 v1 = v0 * 10 + n = n shift v to left and add n + 11 = 1 + 10 + 0 v2 = v1 * 10 + n + 111 = 1 + 10 + 100 v3 = v2 * 10 + n +''' def getUniformIntegerCountInInterval(A: int, B: int) -> int: - first_uniform_int_id = 0 - last_uniform_int_id = 0 - - ## Convert integer to list of digits - integer_digits = [] - while A > 0: - integer_digits.append(A % 10) - A = A // 10 - - ## Loop through digits from left to right - first_digit = integer_digits[-1] - for i in range(len(integer_digits) - 2, -1, -1): - ## The uniform integer is greater than A - if integer_digits[i] < first_digit: - break - - ## The uniform integer is less than A - if integer_digits[i] > first_digit: - first_digit += 1 - break - - ## Map uniform integer to its counting ID - first_uniform_int_id = (9 * (len(integer_digits) - 1)) + first_digit - - ## Convert integer to list of digits - integer_digits = [] - while B > 0: - integer_digits.append(B % 10) - B = B // 10 - - ## Loop through digits from left to right - first_digit = integer_digits[-1] - for i in range(len(integer_digits) - 2, -1, -1): - ## The uniform integer is less than B - if integer_digits[i] > first_digit: - break - - ## The uniform integer is greater than B - if integer_digits[i] < first_digit: - first_digit -= 1 - break - - ## Map uniform integer to its counting ID - last_uniform_int_id = (9 * (len(integer_digits) - 1)) + first_digit - - return last_uniform_int_id - first_uniform_int_id + 1 + total = 0 + for i in range(1, 10): # O(9) + v = i + while v <= B: # O(log(B)) + if A <= v <=B: + total += 1 + v = v * 10 + i + return total ## Test Cases if __name__ == "__main__":