Python 1054.py
class Solution:
def rearrangeBarcodes(self, barcodes: List[int]) -> List[int]:
freq = defaultdict(int)
for b in barcodes:
freq[b] += 1
# max-heap
next = []
for f in freq:
heappush(next, (-freq[f], f)) # negate => max instead of min-heap
result = [ None ] # placeholder
while len(next) >= 2:
# choose most frequent or second most frequent
one = heappop(next)
two = heappop(next)
if result[-1] == one[1]:
two = (two[0] + 1, two[1]) # remember: inverted sign
result.append(two[1])
else:
one = (one[0] + 1, one[1])
result.append(one[1])
if one[0] != 0:
heappush(next, one)
if two[0] != 0:
heappush(next, two)
return result[1:] + [ next[0][1] ] # remove placeholder, add last barcode
Difficulty
and has an acceptance rate of about 49% (100k+ submissions).
AI Disclaimer
However, two years later I set up this website and used various AI tools to generate most of the walkthrough / explanations below.
See this dedicated page for more details.
Code Walkthrough
Overview
The rearrangeBarcodes method receives a list of integers representing barcodes and returns a new ordering where identical values never appear consecutively. The algorithm relies on frequency counting and a max-heap to always select the most abundant barcode that does not violate the adjacency rule.
Key Steps
Frequency Counting
The first phase builds a mapping from each barcode value to its occurrence count.
freq = defaultdict(int)
for b in barcodes:
freq[b] += 1
Building a Max-Heap
Each distinct barcode together with its negative frequency is pushed onto a heap. The negative sign turns Python’s min-heap into a max-heap, allowing the most frequent element to be retrieved efficiently.
next = []
for f in freq:
heappush(next, (-freq[f], f)) # negate => max instead of min-heap
Result Initialization
A placeholder element is placed at the start of the result list. This simplifies the adjacency check for the first real barcode.
result = [ None ] # placeholder
Main Loop - Selecting Two Candidates
While at least two distinct barcodes remain in the heap, the two entries with the highest remaining counts are removed. The algorithm then decides which one can be placed next without repeating the previous value. If the most recent entry in result matches the first candidate, the second candidate is chosen; otherwise the first candidate is used. After placement, the selected candidate’s count is incremented (remembering that the stored count is negative) and any candidate whose count is still non-zero is pushed back onto the heap.
while len(next) >= 2:
one = heappop(next)
two = heappop(next)
if result[-1] == one[1]:
two = (two[0] + 1, two[1]) # remember: inverted sign
result.append(two[1])
else:
one = (one[0] + 1, one[1])
result.append(one[1])
if one[0] != 0:
heappush(next, one)
if two[0] != 0:
heappush(next, two)
Final Assembly
When the loop exits, at most one barcode type remains in the heap. The placeholder is removed, and the final remaining barcode is appended to complete the sequence.
return result[1:] + [ next[0][1] ] # remove placeholder, add last barcode
Edge Cases Handled
When the input contains only a single barcode value, the frequency map holds one entry, the heap contains a single tuple, and the main loop is bypassed because the condition len(next) >= 2 is false. The final return statement appends that sole barcode after discarding the placeholder, yielding a correct one-element result.
If the most frequent barcode appears consecutively in the original list, the adjacency check result[-1] == one[1] forces the algorithm to select the second most frequent barcode for the next position, guaranteeing that no two identical values become neighbors.
The placeholder None ensures that the first real barcode can be compared without a special-case branch; the comparison simply fails because None never equals a valid barcode value.
When the heap reduces to a single entry with a remaining count greater than one, the loop has already exhausted all other types, and the final concatenation adds the remaining barcode exactly once. The earlier decrements guarantee that any additional occurrences would have been placed earlier, so the final sequence respects the adjacency rule.
Performance Optimizations
The use of a heap provides logarithmic-time selection and reinsertion of the most frequent elements, avoiding linear scans of the frequency map at each step. Storing frequencies as negative integers eliminates the need for a custom comparator, leveraging the built-in heap implementation directly. Updating counts in place (one[0] + 1) and immediately pushing back only non-zero entries keeps the heap size minimal, reducing the number of heap operations. The placeholder technique eliminates conditional branching for the first insertion, streamlining the main loop’s logic. Together, these choices produce an efficient rearrangement process that scales well with the number of distinct barcode values.
ELI5 - Simplified Explanation
Imagine you have a big bucket full of colorful toy blocks, and some colors appear much more often than others. The goal is to line them all up in a row, but there is a rule that no two blocks of the same color can touch each other.
To solve this, the code first looks at all the blocks and counts how many there are of each color. It uses a special tool called a heap that is like a smart basket which always keeps the colors with the most blocks sitting right on top so they are easy to grab.
The code picks the two most frequent colors from the basket. It checks which one is safe to place next in the line so that no color sits right next to its twin. After placing a block, it puts the remaining blocks of that color back into the basket if there are still any left. By always picking from the most common colors, it ensures that even the busiest colors get spread out safely across the line. This continues over and over until every single block is placed in a perfect row where every neighbor has a different color.
Code Quality
Complexity Analysis
As a rule of thumb, the maximum input size for one second execution time is
- factorial: up to 10 elements
- exponential: up to 20 elements
- polynomial: a few thousand elements
- loglinear: up to 100,000 elements
- linear: a few million elements
- logarithmic: a billion elements
- constant: practically unlimited
Other Solutions
Obviously, I did that after I solved the problem myself.
In general, AlgoMonster and WalkCCC solutions are high-quality and always worth a look.
I haven't checked most of the other solutions, but they might be helpful as well.
And of course, the LeetCode forum is always a good place (or even the best) to look for alternative approaches.
(click on a column header to sort the table)
| author | ||||||||
|---|---|---|---|---|---|---|---|---|
| author | solutions | |||||||
| www | AlgoMonster | C++ | Python | Java | TS | |||
| WalkCCC | C++ | Python | Java | |||||
| leetcode.ca | C++ | Python | Java | Go | TS | |||
| LeetcodeHelp | C++ | Python | Java | |||||
| Progiez | C++ | Python | Java | |||||
| github | black-shadows | C++ | ||||||
| charles-wangkai | Java | |||||||
| everthis | JS | |||||||
| fsq | C++ | |||||||
| Garvit244 | Python | |||||||
| gouthampradhan | Java | |||||||
| halfrost | Go | |||||||
| JoshCrozier | JS | |||||||
| keineahnung2345 | C++ | |||||||
| lkwq007 | Python | |||||||
| suxrobGM | C# | |||||||
| trung-hn | Python | |||||||
| wisdompeak | C++ | |||||||
| AlgoMonster | C++, Python, Java, TypeScript | |||||||
| WalkCCC | C++, Python, Java | |||||||
| leetcode.ca | C++, Go, Java, Python, TypeScript | |||||||
| LeetcodeHelp | C++, Java, Python | |||||||
| Progiez | C++, Java, Python | |||||||
| black-shadows | C++, C++ | |||||||
| charles-wangkai | Java | |||||||
| everthis | JavaScript | |||||||
| fsq | C++ | |||||||
| Garvit244 | Python | |||||||
| gouthampradhan | Java | |||||||
| halfrost | Go | |||||||
| JoshCrozier | JavaScript | |||||||
| keineahnung2345 | C++ | |||||||
| lkwq007 | Python | |||||||
| suxrobGM | C# | |||||||
| trung-hn | Python | |||||||
| wisdompeak | C++ |
Videos
Solved On The Same Day
- problem 880: Decoded String at Index
- problem 912: Sort an Array
- problem 923: 3Sum With Multiplicity
- problem 973: K Closest Points to Origin
- problem 1010: Pairs of Songs With Total Durations Divisible by 60
- problem 1079: Letter Tile Possibilities
- problem 1090: Largest Values From Labels
- problem 1347: Minimum Number of Steps to Make Two Strings Anagram
- problem 1366: Rank Teams by Votes
- problem 1419: Minimum Number of Frogs Croaking
- problem 1738: Find Kth Largest XOR Coordinate Value
- problem 1814: Count Nice Pairs in an Array
- problem 1985: Find the Kth Largest Integer in the Array
- problem 2018: Check if Word Can Be Placed In Crossword
- problem 2150: Find All Lonely Numbers in the Array
- problem 2182: Construct String With Repeat Limit
- problem 2225: Find Players With Zero or One Losses
- problem 2232: Minimize Result by Adding Parentheses to Expression
- problem 2244: Minimum Rounds to Complete All Tasks
- problem 2284: Sender With Largest Word Count
- problem 2343: Query Kth Smallest Trimmed Number
- problem 2526: Find Consecutive Integers from a Data Stream
- problem 2844: Minimum Operations to Make a Special Number
- problem 2860: Happy Students
- problem 906: Super Palindromes
- problem 992: Subarrays with K Different Integers
- problem 1106: Parsing A Boolean Expression
- problem 1601: Maximum Number of Achievable Transfer Requests
- problem 2081: Sum of k-Mirror Numbers
- problem 2122: Recover the Original Array
- problem 2416: Sum of Prefix Scores of Strings
Extra
- Tech Stack - my development environment and tools
- AI - how AI helped me create this website (NOT solving the problems)
- Progress - progression over time
- Quality - code quality