Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Last Stone Weight in Python
The Last Stone Weight problem simulates repeatedly smashing the two heaviest stones together until at most one stone remains. When two stones with weights x and y collide (where x ? y), they either both get destroyed if equal, or the lighter stone is destroyed and the heavier one becomes y - x.
Problem Rules
- If x = y, then both stones are totally destroyed
- If x ? y, the stone of weight x is destroyed, and the stone of weight y becomes y - x
For example, with stones [2,7,4,1,8,1]:
- Smash 8 and 7 ? get stone of weight 1, array becomes [2,4,1,1,1]
- Smash 4 and 2 ? get stone of weight 2, array becomes [2,1,1,1]
- Smash 2 and 1 ? get stone of weight 1, array becomes [1,1,1]
- Smash 1 and 1 ? both destroyed, array becomes [1]
- Final answer: 1
Algorithm Steps
- If stone array is empty, return 0
- If array has only one element, return that element
- While array has more than one element:
- Sort the array to find heaviest stones
- Take the two heaviest stones (last two elements)
- If weights are equal, remove both stones
- Otherwise, replace heavier stone with their difference
- Return remaining stone weight or 0 if none left
Implementation
class Solution:
def lastStoneWeight(self, stones):
if len(stones) == 0:
return 0
if len(stones) == 1:
return stones[0]
while len(stones) > 1:
stones.sort()
s1, s2 = stones[-1], stones[-2]
if s1 == s2:
stones.pop(-1) # Remove heaviest
stones.pop(-1) # Remove second heaviest
else:
s1 = abs(s1 - s2)
stones.pop(-1) # Remove heaviest
stones[-1] = s1 # Replace second heaviest with difference
if len(stones):
return stones[-1]
return 0
# Test the solution
solution = Solution()
result = solution.lastStoneWeight([2, 7, 4, 1, 6, 1])
print(f"Last stone weight: {result}")
Last stone weight: 1
Step-by-Step Execution
Let's trace through the example [2, 7, 4, 1, 6, 1]:
def trace_execution(stones):
stones = stones.copy() # Don't modify original
step = 1
while len(stones) > 1:
stones.sort()
print(f"Step {step}: Sorted stones = {stones}")
s1, s2 = stones[-1], stones[-2]
print(f" Smashing stones {s2} and {s1}")
if s1 == s2:
stones.pop(-1)
stones.pop(-1)
print(f" Both destroyed. Remaining: {stones}")
else:
diff = abs(s1 - s2)
stones.pop(-1)
stones[-1] = diff
print(f" New stone of weight {diff}. Remaining: {stones}")
step += 1
return stones[0] if stones else 0
result = trace_execution([2, 7, 4, 1, 6, 1])
print(f"\nFinal result: {result}")
Step 1: Sorted stones = [1, 1, 2, 4, 6, 7] Smashing stones 6 and 7 New stone of weight 1. Remaining: [1, 1, 2, 4, 1] Step 2: Sorted stones = [1, 1, 1, 2, 4] Smashing stones 2 and 4 New stone of weight 2. Remaining: [1, 1, 1, 2] Step 3: Sorted stones = [1, 1, 1, 2] Smashing stones 1 and 2 New stone of weight 1. Remaining: [1, 1, 1] Step 4: Sorted stones = [1, 1, 1] Smashing stones 1 and 1 Both destroyed. Remaining: [1] Final result: 1
Time Complexity
The time complexity is O(n² log n) because we sort the array in each iteration, and there can be up to n iterations. The space complexity is O(1) as we modify the input array in-place.
Conclusion
The Last Stone Weight problem uses a greedy approach by repeatedly smashing the two heaviest stones. The simulation continues until at most one stone remains, making it an excellent example of array manipulation and sorting algorithms.
