-
Notifications
You must be signed in to change notification settings - Fork 2
feat(algorithms, greedy): largest palindromic number #156
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
BrianLusina
merged 4 commits into
main
from
feat/algorithms-greedy-largest-palindromic-number
Jan 21, 2026
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
ba76352
feat(algorithms, greedy): largest palindromic number
BrianLusina b61d214
updating DIRECTORY.md
a093cf2
test(algorithms, greedy, largest-palindromic-number): additional test…
BrianLusina 4ea8684
Update algorithms/greedy/largest_palindromic_number/README.md
BrianLusina File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| # Largest Palindromic Number | ||
|
|
||
| You are given a string num consisting of digits from 0 to 9. Your task is to return the largest possible palindromic | ||
| number as a string by using some or all of the digits in num. | ||
|
|
||
| The resulting palindromic number must not have leading zeros. | ||
|
|
||
| > Note: You may reorder the digits freely, and you must use at least one digit from the num string. | ||
|
|
||
| ## Constraints | ||
|
|
||
| - 1 <= `num.length` <= 1000 | ||
| - `num` consists of digits | ||
|
|
||
| ## Examples | ||
|
|
||
|  | ||
|  | ||
|  | ||
|
|
||
| ## Solution | ||
|
|
||
| We will use the greedy pattern to solve this problem. The goal is to maximize the size of the palindrome by making | ||
| locally optimal choices at each step. Specifically, we aim to form the largest possible palindrome by first prioritizing | ||
| using the highest digits. | ||
|
|
||
| The process begins by counting the frequency of each digit in the input string and storing it in a hash table. This | ||
| allows us to determine how many times each digit appears. Starting with the highest digit, i.e., 9, and working down to | ||
| the lowest, i.e., 0, we try to use the possible pairs of each digit to form the first half of the palindrome. This | ||
| ensures that the most significant positions in the palindrome are filled with the largest digits. Out of the leftover | ||
| single digits, the highest possible digit can be used as the middle digit to further enhance the size of the palindrome. | ||
|
|
||
| Finally, the palindrome is completed by appending the reverse of the first half to itself, with the middle digit in | ||
| between, if applicable. This greedy strategy works effectively because it ensures that each decision made is the best | ||
| possible choice at that moment, leading to an overall optimal solution. | ||
|
|
||
| Let’s review the algorithm to reach the solution: | ||
|
|
||
| - Initialize the frequency counter occurrences to count the frequency of each digit in the input string num. | ||
| - We also initialize the first_half array to note down the first part of the palindrome and the middle string to track | ||
| the middle element of the palindrome. | ||
| - Traverse digits from 9 to 0 and for each digit do the following: | ||
| - Check if its pairs can be made by looking at its frequency. If yes, then add it to the first_half array. | ||
| - If applicable, check for the leading zeros and avoid them by explicitly setting their occurrence to 1. | ||
| - Otherwise, check if it can be the middle element of the palindrome. Following the greedy approach, ensures that a | ||
| larger number is selected to be the middle element among the elements occurring once. | ||
|
|
||
| - Once we have processed all the elements of the num array, we join the first_half, middle, and reverse of the first_half. | ||
| - Finally, we return this palindromic number, the largest that can be generated using the given number. | ||
|
|
||
|  | ||
|  | ||
|  | ||
|  | ||
|  | ||
|  | ||
|  | ||
|  | ||
|  | ||
|
|
||
| ### Time Complexity | ||
|
|
||
| The time complexity of the solution is O(n), where n is the length of the num string. | ||
|
|
||
| ### Space Complexity | ||
|
|
||
| The space complexity of the solution is O(n). In the worst case, first_half could store up to n/2 digits if all digits | ||
| are the same. Therefore, the space for first_half is O(n). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| from collections import Counter | ||
|
|
||
|
|
||
| def largest_palindromic_number(num: str) -> str: | ||
| # Count the frequency of each digit in the input string | ||
| occureneces = Counter(num) | ||
|
|
||
| # first half and the middle of the palindrome | ||
| first_half = [] | ||
| middle = "" | ||
|
|
||
| for digit in range(9, -1, -1): | ||
| digit_char = str(digit) | ||
|
|
||
| if digit_char in occureneces: | ||
| digit_count = occureneces[digit_char] | ||
|
|
||
| # num of pairs of this digit that can be used | ||
| num_pairs = digit_count // 2 | ||
|
|
||
| # If pairs available, add them to the first half | ||
| if num_pairs: | ||
| # Avoiding leading zeros | ||
| if not first_half and not digit: | ||
| occureneces["0"] = 1 | ||
| else: | ||
| first_half.append(digit_char * num_pairs) | ||
|
|
||
| # Checking for a middle element | ||
| if digit_count % 2 and not middle: | ||
| middle = digit_char | ||
|
|
||
| # If all elements are '0' | ||
| if not middle and not first_half: | ||
| return "0" | ||
|
|
||
| # Returning the full palindrome | ||
| return "".join(first_half + [middle] + first_half[::-1]) | ||
|
|
||
|
|
||
| def largest_palindromic_number_v2(num: str) -> str: | ||
| # Count how many times each digit appears | ||
| digit_counter = Counter(num) | ||
|
|
||
| result = "" | ||
| # Find the middle digit by counting down from 9 to 0 while decrementing the count of a digit that appears an odd | ||
| # number of times | ||
| for digit in range(9, 0, -1): | ||
| digit_str = str(digit) | ||
| if digit_counter[digit_str] % 2 == 1: | ||
| result = digit_str | ||
| # decrement the count of this digit | ||
| digit_counter[digit_str] -= 1 | ||
| break | ||
|
|
||
| # Build symmetric pairs by iterating from 0 to 9 for each digit with remaining count | ||
| for number in range(10): | ||
| number_str = str(number) | ||
| if digit_counter[number_str] > 0: | ||
| # Divide by two to get number of pairs | ||
| digit_counter[number_str] //= 2 | ||
| temp = digit_counter[number_str] * number_str | ||
| result = f"{temp}{result}{temp}" | ||
|
|
||
| return result.strip("0") or "0" | ||
BrianLusina marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Binary file added
BIN
+77.3 KB
...est_palindromic_number/images/examples/largest_palindromic_number_example_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+77.4 KB
...est_palindromic_number/images/examples/largest_palindromic_number_example_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+89.1 KB
...est_palindromic_number/images/examples/largest_palindromic_number_example_3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+85.1 KB
...t_palindromic_number/images/solutions/largest_palindromic_number_solution_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+71.2 KB
...t_palindromic_number/images/solutions/largest_palindromic_number_solution_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+86.3 KB
...t_palindromic_number/images/solutions/largest_palindromic_number_solution_3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+77.5 KB
...t_palindromic_number/images/solutions/largest_palindromic_number_solution_4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+82.2 KB
...t_palindromic_number/images/solutions/largest_palindromic_number_solution_5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+86.1 KB
...t_palindromic_number/images/solutions/largest_palindromic_number_solution_6.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+83.8 KB
...t_palindromic_number/images/solutions/largest_palindromic_number_solution_7.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+95.1 KB
...t_palindromic_number/images/solutions/largest_palindromic_number_solution_8.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+109 KB
...t_palindromic_number/images/solutions/largest_palindromic_number_solution_9.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 32 additions & 0 deletions
32
algorithms/greedy/largest_palindromic_number/test_largest_palindromic_number.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| import unittest | ||
| from parameterized import parameterized | ||
| from algorithms.greedy.largest_palindromic_number import ( | ||
| largest_palindromic_number, | ||
| largest_palindromic_number_v2, | ||
| ) | ||
|
|
||
| LARGEST_PALINDROMIC_NUMBER_TEST_CASES = [ | ||
| ("2012", "212"), | ||
| ("000001", "1"), | ||
| ("111222333", "3213123"), | ||
| ("000000", "0"), | ||
| ("123456789123456789", "987654321123456789"), | ||
| ("444947137", "7449447"), | ||
| ("00009", "9"), | ||
| ] | ||
|
|
||
|
|
||
| class LargestPalindromicNumberTestCase(unittest.TestCase): | ||
| @parameterized.expand(LARGEST_PALINDROMIC_NUMBER_TEST_CASES) | ||
| def test_largest_palindromic_number(self, num: str, expected: str): | ||
| actual = largest_palindromic_number(num) | ||
| self.assertEqual(expected, actual) | ||
|
|
||
| @parameterized.expand(LARGEST_PALINDROMIC_NUMBER_TEST_CASES) | ||
| def test_largest_palindromic_number_v2(self, num: str, expected: str): | ||
| actual = largest_palindromic_number_v2(num) | ||
| self.assertEqual(expected, actual) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| unittest.main() |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.