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
Pairs of Songs With Total Durations Divisible by 60 in Python
Finding pairs of songs with total durations divisible by 60 is a common algorithmic problem. We can solve this efficiently using the remainder approach with a hash map to track remainders when dividing by 60.
Problem Understanding
Given a list of song durations, we need to count pairs where the sum is divisible by 60. For example, with [30, 20, 150, 100, 40], we get 3 pairs: (30, 150), (20, 100), and (20, 40) since 180, 120, and 60 are all divisible by 60.
Algorithm Approach
The key insight is using modular arithmetic:
- Two numbers sum to a multiple of 60 if their remainders add to 60 (or both are 0)
- Track remainder frequencies in a hash map
- For each song, check if its complement remainder exists
- Special case: songs with 0 remainder (divisible by 60) pair with each other
Solution Implementation
def numPairsDivisibleBy60(time):
ans = 0
remainder = {}
for duration in time:
current_remainder = duration % 60
if current_remainder == 0 and 0 in remainder:
# Songs divisible by 60 pair with other songs divisible by 60
ans += remainder[0]
elif (60 - current_remainder) in remainder:
# Find complement remainder
ans += remainder[60 - current_remainder]
# Update remainder frequency
if current_remainder in remainder:
remainder[current_remainder] += 1
else:
remainder[current_remainder] = 1
return ans
# Test the function
time_list = [30, 20, 150, 100, 40]
result = numPairsDivisibleBy60(time_list)
print(f"Number of pairs: {result}")
# Show the actual pairs for verification
print("\nPairs found:")
for i in range(len(time_list)):
for j in range(i + 1, len(time_list)):
if (time_list[i] + time_list[j]) % 60 == 0:
print(f"({time_list[i]}, {time_list[j]}) = {time_list[i] + time_list[j]}")
Number of pairs: 3 Pairs found: (30, 150) = 180 (20, 100) = 120 (20, 40) = 60
How It Works
The algorithm works by tracking remainder frequencies:
- Remainder 30: Needs remainder 30 to sum to 60
- Remainder 20: Needs remainder 40 to sum to 60
- Remainder 0: Pairs with other remainder 0 values
Optimized Version
Here's a cleaner implementation using Python's defaultdict ?
from collections import defaultdict
def numPairsDivisibleBy60Optimized(time):
remainder_count = defaultdict(int)
pairs = 0
for duration in time:
remainder = duration % 60
complement = (60 - remainder) % 60
pairs += remainder_count[complement]
remainder_count[remainder] += 1
return pairs
# Test with the same example
time_list = [30, 20, 150, 100, 40]
result = numPairsDivisibleBy60Optimized(time_list)
print(f"Number of pairs (optimized): {result}")
Number of pairs (optimized): 3
Time and Space Complexity
| Aspect | Complexity | Explanation |
|---|---|---|
| Time | O(n) | Single pass through the array |
| Space | O(1) | At most 60 different remainders |
Conclusion
This problem efficiently demonstrates using modular arithmetic and hash maps for counting pairs. The key insight is that two numbers sum to a multiple of 60 when their remainders complement each other to 60.
