Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 18 additions & 69 deletions Level 1/Uniform_Integers.py
Original file line number Diff line number Diff line change
Expand Up @@ -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__":
Expand Down