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
Program to find maximum sum obtained of any permutation in Python
Given an array nums and an array requests where requests[i] = [start_i, end_i], each request asks for the sum of elements from nums[start_i] to nums[end_i] inclusive. We need to find the maximum total sum of all requests among all permutations of nums. The answer should be returned modulo 10^9+7.
Problem Understanding
For example, if nums = [10,20,30,40,50] and requests = [[1,3],[0,1]], we want to arrange the array to maximize the sum. The optimal arrangement [30,50,40,20,10] gives ?
- Request [1,3]: nums[1] + nums[2] + nums[3] = 50 + 40 + 20 = 110
- Request [0,1]: nums[0] + nums[1] = 30 + 50 = 80
- Total sum: 110 + 80 = 190
Algorithm
The key insight is to determine how many times each position gets accessed across all requests, then place larger numbers at positions that are accessed more frequently.
Step 1: Create Events
For each request [start, end], we create start and end events to track when ranges begin and end ?
from collections import defaultdict
def solve(nums, requests):
# Create events for range starts and ends
events = []
for start, end in requests:
events.append((start, 0)) # 0 for range start
events.append((end, 1)) # 1 for range end
events.sort()
print("Events:", events)
# Calculate frequency for each position range
freq_ranges = defaultdict(list)
active_count = 0
i = 0
n = len(events)
while i < n:
# Count duplicate events at same position
duplicates = 1
while i < n - 1 and events[i+1] == events[i]:
duplicates += 1
i += 1
position, event_type = events[i]
if event_type == 0: # Range start
active_count += duplicates
if active_count - duplicates > 0:
freq_ranges[active_count - duplicates].append((prev_pos, position - 1))
prev_pos = position
else: # Range end
active_count -= duplicates
freq_ranges[active_count + duplicates].append((prev_pos, position))
prev_pos = position + 1
i += 1
print("Frequency ranges:", dict(freq_ranges))
return freq_ranges
nums = [10, 20, 30, 40, 50]
requests = [[1, 3], [0, 1]]
freq_ranges = solve(nums, requests)
Events: [(0, 0), (1, 0), (1, 1), (3, 1)]
Frequency ranges: {1: [(0, 0), (2, 3)], 2: [(1, 1)]}
Step 2: Assign Values Optimally
Sort numbers in descending order and assign them to positions with highest frequency first ?
from collections import defaultdict
def solve(nums, requests):
# Create events for range processing
events = []
for start, end in requests:
events.append((start, 0)) # Range start
events.append((end, 1)) # Range end
events.sort()
# Calculate frequency for each position range
freq_ranges = defaultdict(list)
active_count = 0
i = 0
n = len(events)
prev_pos = 0
while i < n:
duplicates = 1
while i < n - 1 and events[i+1] == events[i]:
duplicates += 1
i += 1
position, event_type = events[i]
if event_type == 0: # Range start
active_count += duplicates
if active_count - duplicates > 0:
freq_ranges[active_count - duplicates].append((prev_pos, position - 1))
prev_pos = position
else: # Range end
active_count -= duplicates
freq_ranges[active_count + duplicates].append((prev_pos, position))
prev_pos = position + 1
i += 1
# Sort numbers in descending order
nums.sort(reverse=True)
# Sort frequencies in descending order
frequencies = list(freq_ranges.keys())
frequencies.sort(reverse=True)
# Calculate maximum sum
result = 0
MOD = 10**9 + 7
num_index = 0
for freq in frequencies:
for start, end in freq_ranges[freq]:
range_length = end - start + 1
range_sum = sum(nums[num_index:num_index + range_length])
result += range_sum * freq
result %= MOD
num_index += range_length
return result
# Test the solution
nums = [10, 20, 30, 40, 50]
requests = [[1, 3], [0, 1]]
print("Maximum sum:", solve(nums, requests))
Maximum sum: 190
How It Works
The algorithm works by ?
- Event Processing: Convert range requests into start/end events
- Frequency Calculation: Count how many requests overlap at each position
- Optimal Assignment: Place largest numbers at positions accessed most frequently
- Sum Calculation: Multiply each range sum by its access frequency
Complete Solution
from collections import defaultdict
def maximumSumPermutation(nums, requests):
# Create events for range boundaries
events = []
for start, end in requests:
events.append((start, 0)) # 0 = range start
events.append((end, 1)) # 1 = range end
events.sort()
# Calculate frequency for each position range
freq_ranges = defaultdict(list)
active_count = 0
i = 0
n = len(events)
prev_pos = 0
while i < n:
# Handle duplicate events at same position
duplicates = 1
while i < n - 1 and events[i+1] == events[i]:
duplicates += 1
i += 1
position, event_type = events[i]
if event_type == 0: # Range start
active_count += duplicates
if active_count - duplicates > 0:
freq_ranges[active_count - duplicates].append((prev_pos, position - 1))
prev_pos = position
else: # Range end
active_count -= duplicates
freq_ranges[active_count + duplicates].append((prev_pos, position))
prev_pos = position + 1
i += 1
# Sort numbers in descending order for optimal placement
nums.sort(reverse=True)
# Process frequencies in descending order
frequencies = sorted(freq_ranges.keys(), reverse=True)
result = 0
MOD = 10**9 + 7
num_index = 0
# Assign numbers to positions based on frequency
for freq in frequencies:
for start, end in freq_ranges[freq]:
range_length = end - start + 1
range_sum = sum(nums[num_index:num_index + range_length])
result = (result + range_sum * freq) % MOD
num_index += range_length
return result
# Test with example
nums = [10, 20, 30, 40, 50]
requests = [[1, 3], [0, 1]]
print("Result:", maximumSumPermutation(nums, requests))
Result: 190
Conclusion
This solution uses an event-based approach to calculate position frequencies, then optimally assigns the largest numbers to the most frequently accessed positions. The time complexity is O(n log n) for sorting, making it efficient for large inputs.
