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
Longest Well-Performing Interval in Python
The Longest Well-Performing Interval problem requires finding the longest subarray where tiring days (hours > 8) outnumber non-tiring days. We solve this using a prefix sum approach with a hashmap to track cumulative balance efficiently.
Understanding the Problem
A tiring day occurs when hours worked > 8. A well-performing interval is a subarray where tiring days strictly outnumber non-tiring days. We transform each day into +1 (tiring) or -1 (non-tiring) and find the longest subarray with positive sum.
Algorithm Approach
We use a prefix sum technique with the following key insights:
- Convert hours to +1 (if > 8) or -1 (if ? 8)
- Track cumulative sum to identify well-performing intervals
- Use hashmap to store first occurrence of each sum
- When sum > 0, entire prefix is well-performing
- When sum ? 0, look for previous sum-1 to find valid interval
Implementation
def longestWPI(hours):
"""
Find the length of the longest well-performing interval.
Args:
hours: List of integers representing daily work hours
Returns:
Length of longest interval where tiring days > non-tiring days
"""
cumulative_sum = 0
max_length = 0
sum_positions = {} # Maps cumulative sum to first occurrence index
for i, hour in enumerate(hours):
# Convert to +1 for tiring day (>8), -1 for non-tiring day (?8)
cumulative_sum += 1 if hour > 8 else -1
if cumulative_sum > 0:
# Entire prefix from start is well-performing
max_length = i + 1
else:
# Record first occurrence of this sum
if cumulative_sum not in sum_positions:
sum_positions[cumulative_sum] = i
# Look for sum-1 to find a valid well-performing interval
if cumulative_sum - 1 in sum_positions:
interval_length = i - sum_positions[cumulative_sum - 1]
max_length = max(max_length, interval_length)
return max_length
# Test with the given example
hours = [9, 9, 6, 0, 6, 6, 9]
result = longestWPI(hours)
print(f"Hours: {hours}")
print(f"Longest well-performing interval length: {result}")
Hours: [9, 9, 6, 0, 6, 6, 9] Longest well-performing interval length: 3
Step-by-Step Trace
Let's trace through the example [9, 9, 6, 0, 6, 6, 9]:
def longestWPI_with_trace(hours):
cumulative_sum = 0
max_length = 0
sum_positions = {}
print("Day | Hours | Tiring? | Sum | Action")
print("-" * 45)
for i, hour in enumerate(hours):
is_tiring = hour > 8
cumulative_sum += 1 if is_tiring else -1
action = ""
if cumulative_sum > 0:
max_length = i + 1
action = f"Prefix length: {i + 1}"
else:
if cumulative_sum not in sum_positions:
sum_positions[cumulative_sum] = i
action = f"Record sum {cumulative_sum} at index {i}"
if cumulative_sum - 1 in sum_positions:
interval_length = i - sum_positions[cumulative_sum - 1]
max_length = max(max_length, interval_length)
action += f" | Found interval length: {interval_length}"
print(f"{i:3} | {hour:5} | {str(is_tiring):7} | {cumulative_sum:3} | {action}")
return max_length
# Trace the example
result = longestWPI_with_trace([9, 9, 6, 0, 6, 6, 9])
print(f"\nFinal result: {result}")
Day | Hours | Tiring? | Sum | Action --------------------------------------------- 0 | 9 | True | 1 | Prefix length: 1 1 | 9 | True | 2 | Prefix length: 2 2 | 6 | False | 1 | Prefix length: 3 3 | 0 | False | 0 | Record sum 0 at index 3 4 | 6 | False | -1 | Record sum -1 at index 4 5 | 6 | False | -2 | Record sum -2 at index 5 | Found interval length: 1 6 | 9 | True | -1 | Found interval length: 2 Final result: 3
Time and Space Complexity
| Aspect | Complexity | Explanation |
|---|---|---|
| Time | O(n) | Single pass through the array |
| Space | O(n) | Hashmap stores at most n different sums |
Conclusion
The algorithm efficiently finds the longest well-performing interval using prefix sums and a hashmap. The key insight is transforming the problem into finding the longest subarray with positive sum, achieved in O(n) time complexity.
---