Skip to content

Commit cbcb729

Browse files
authored
Merge pull request #173 from BrianLusina/feat/algorithms-greedy-max-swap
feat(algorithms, greedy): max swap
2 parents aff77c8 + 63a5dad commit cbcb729

15 files changed

Lines changed: 505 additions & 4 deletions

DIRECTORY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,8 @@
174174
* [Test Largest Palindromic Number](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/greedy/largest_palindromic_number/test_largest_palindromic_number.py)
175175
* Majority Element
176176
* [Test Majority Element](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/greedy/majority_element/test_majority_element.py)
177+
* Maximum Swap
178+
* [Test Maximum Swap](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/greedy/maximum_swap/test_maximum_swap.py)
177179
* Min Arrows
178180
* [Test Find Min Arrows](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/greedy/min_arrows/test_find_min_arrows.py)
179181
* Minimum Number Of Pushes

algorithms/greedy/maximum_swap/README.md

Lines changed: 354 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
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
25.6 KB
Loading
21.7 KB
Loading
27.8 KB
Loading
27 KB
Loading
30.4 KB
Loading
30.1 KB
Loading
29.3 KB
Loading

0 commit comments

Comments
 (0)