|
| 1 | +from typing import List |
| 2 | + |
| 3 | + |
| 4 | +def maximum_swap(num: int) -> int: |
| 5 | + # Convert the number to a list of characters for easy manipulation |
| 6 | + digits: List[str] = list(str(num)) |
| 7 | + n = len(digits) |
| 8 | + |
| 9 | + # Variables to track the index of the maximum digit and the two swap indices |
| 10 | + max_digit_index = index_1 = index_2 = -1 |
| 11 | + |
| 12 | + # Iterate the string from the last digit to the first |
| 13 | + for i in range(n - 1, -1, -1): |
| 14 | + # Update the max digit index if the current digit is greater |
| 15 | + if max_digit_index == -1 or digits[i] > digits[max_digit_index]: |
| 16 | + max_digit_index = i |
| 17 | + # If the current digit is less than the max digit found so far, |
| 18 | + # mark this index (index_1) and the max digit's index (index_2) for swapping |
| 19 | + elif digits[i] < digits[max_digit_index]: |
| 20 | + index_1 = i |
| 21 | + index_2 = max_digit_index |
| 22 | + |
| 23 | + # Perform the swap if valid indices are found |
| 24 | + if index_1 != -1 and index_2 != -1: |
| 25 | + digits[index_1], digits[index_2] = digits[index_2], digits[index_1] |
| 26 | + |
| 27 | + # Convert the list back to an integer and return it |
| 28 | + return int("".join(digits)) |
| 29 | + |
| 30 | + |
| 31 | +def maximum_swap_suboptimal_greedy(num: int) -> int: |
| 32 | + num_str = str(num) |
| 33 | + n = len(num_str) |
| 34 | + last_seen = [-1] * 10 # Store the last occurrence of each digit |
| 35 | + |
| 36 | + # Record the last occurrence of each digit |
| 37 | + for i in range(n): |
| 38 | + last_seen[int(num_str[i])] = i |
| 39 | + |
| 40 | + # Traverse the string to find the first digit that can be swapped with a larger one |
| 41 | + for i in range(n): |
| 42 | + for d in range(9, int(num_str[i]), -1): |
| 43 | + if last_seen[d] > i: |
| 44 | + # Perform the swap |
| 45 | + num_str = list(num_str) |
| 46 | + num_str[i], num_str[last_seen[d]] = ( |
| 47 | + num_str[last_seen[d]], |
| 48 | + num_str[i], |
| 49 | + ) |
| 50 | + num_str = "".join(num_str) |
| 51 | + |
| 52 | + return int(num_str) # Return the new number immediately after the swap |
| 53 | + |
| 54 | + return num # Return the original number if no swap can maximize it |
| 55 | + |
| 56 | + |
| 57 | +def maximum_swap_greedy_two_pass(num: int) -> int: |
| 58 | + num_str = list(str(num)) |
| 59 | + n = len(num_str) |
| 60 | + max_right_index = [0] * n |
| 61 | + |
| 62 | + max_right_index[n - 1] = n - 1 |
| 63 | + for i in range(n - 2, -1, -1): |
| 64 | + max_right_index[i] = ( |
| 65 | + i |
| 66 | + if num_str[i] > num_str[max_right_index[i + 1]] |
| 67 | + else max_right_index[i + 1] |
| 68 | + ) |
| 69 | + |
| 70 | + for i in range(n): |
| 71 | + if num_str[i] < num_str[max_right_index[i]]: |
| 72 | + num_str[i], num_str[max_right_index[i]] = ( |
| 73 | + num_str[max_right_index[i]], |
| 74 | + num_str[i], |
| 75 | + ) |
| 76 | + return int("".join(num_str)) |
| 77 | + |
| 78 | + return num |
| 79 | + |
| 80 | + |
| 81 | +def maximum_swap_brute_force(num: int) -> int: |
| 82 | + num_str = str(num) # Convert num to string for easy manipulation |
| 83 | + n = len(num_str) |
| 84 | + max_num = num # Track the maximum number found |
| 85 | + |
| 86 | + # Try all possible swaps |
| 87 | + for i in range(n): |
| 88 | + for j in range(i + 1, n): |
| 89 | + num_list = list(num_str) # Convert the string to list for swapping |
| 90 | + |
| 91 | + num_list[i], num_list[j] = ( |
| 92 | + num_list[j], |
| 93 | + num_list[i], |
| 94 | + ) # Swap digits at index i and j |
| 95 | + temp = int( |
| 96 | + "".join(num_list) |
| 97 | + ) # Convert the list back to string and then to integer |
| 98 | + |
| 99 | + max_num = max(max_num, temp) # Update max_num if the new number is larger |
| 100 | + |
| 101 | + return max_num # Return the largest number after all possible swaps |
0 commit comments