Sum of Subsequence Widths
HARDDescription
The width of a sequence is the difference between the maximum and minimum elements in the sequence.
Given an array of integers nums, return the sum of the widths of all the non-empty subsequences of nums. Since the answer may be very large, return it modulo 109 + 7.
A subsequence is a sequence that can be derived from an array by deleting some or no elements without changing the order of the remaining elements. For example, [3,6,2,7] is a subsequence of the array [0,3,1,6,2,2,7].
Example 1:
Input: nums = [2,1,3] Output: 6 Explanation: The subsequences are [1], [2], [3], [2,1], [2,3], [1,3], [2,1,3]. The corresponding widths are 0, 0, 0, 1, 1, 2, 2. The sum of these widths is 6.
Example 2:
Input: nums = [2] Output: 0
Constraints:
1 <= nums.length <= 1051 <= nums[i] <= 105
Approaches
Checkout 3 different approaches to solve Sum of Subsequence Widths. Click on different approaches to view the approach and algorithm in detail.
Brute Force by Generating All Subsequences
This approach involves generating every possible non-empty subsequence of the given array. For each subsequence, we find its maximum and minimum elements, calculate the width (max - min), and add it to a running total. This is the most straightforward but also the most inefficient method, as the number of subsequences grows exponentially with the size of the input array.
Algorithm
- Initialize a global variable
totalWidthto 0. - Create a recursive function, say
findSubsequences(index, currentSubsequence), to generate all subsequences. - Base Case: When the
indexreaches the end of the array:- If the
currentSubsequenceis not empty, find its minimum and maximum elements. - Calculate the width (
max - min). - Add the width to
totalWidth, taking modulo10^9 + 7. - Return.
- If the
- Recursive Step: For each element
nums[index], make two recursive calls:- One call that excludes
nums[index]from the subsequence:findSubsequences(index + 1, currentSubsequence). - One call that includes
nums[index]: addnums[index]tocurrentSubsequence, callfindSubsequences(index + 1, currentSubsequence), and then remove it to backtrack.
- One call that excludes
- Start the process by calling
findSubsequences(0, new ArrayList<>()). - Return the final
totalWidth.
The core of this method is a backtracking algorithm to explore all possibilities of forming a subsequence. We can define a recursive helper function that builds subsequences. At each step i in the input array nums, we decide whether to include nums[i] in the current subsequence or not. This creates a decision tree of 2^n paths, where n is the length of nums, with each path corresponding to a unique subsequence. Once a full subsequence is formed (i.e., we've made a decision for every element), we check if it's non-empty. If it is, we iterate through it to find the minimum and maximum values, compute their difference, and add this width to a global sum. All additions are performed modulo 10^9 + 7 to prevent overflow and meet the problem's requirements.
class Solution {
long totalWidth = 0;
int MOD = 1_000_000_007;
public int sumSubsequenceWidths(int[] nums) {
// Note: This approach is too slow and will time out.
findSubsequences(nums, 0, new java.util.ArrayList<>());
return (int) totalWidth;
}
private void findSubsequences(int[] nums, int index, java.util.List<Integer> currentSubsequence) {
if (index == nums.length) {
if (!currentSubsequence.isEmpty()) {
int minVal = Integer.MAX_VALUE;
int maxVal = Integer.MIN_VALUE;
for (int num : currentSubsequence) {
minVal = Math.min(minVal, num);
maxVal = Math.max(maxVal, num);
}
totalWidth = (totalWidth + maxVal - minVal) % MOD;
}
return;
}
// Decision 1: Exclude nums[index]
findSubsequences(nums, index + 1, currentSubsequence);
// Decision 2: Include nums[index]
currentSubsequence.add(nums[index]);
findSubsequences(nums, index + 1, currentSubsequence);
currentSubsequence.remove(currentSubsequence.size() - 1); // Backtrack
}
}
Complexity Analysis
Pros and Cons
- Simple to understand and conceptualize.
- Extremely inefficient due to its exponential time complexity.
- Will result in a 'Time Limit Exceeded' (TLE) error for the given constraints.
Code Solutions
Checking out 3 solutions in different languages for Sum of Subsequence Widths. Click on different languages to view the code.
class Solution { private static final int MOD = ( int ) 1 e9 + 7 ; public int sumSubseqWidths ( int [] nums ) { Arrays . sort ( nums ); long ans = 0 , p = 1 ; int n = nums . length ; for ( int i = 0 ; i < n ; ++ i ) { ans = ( ans + ( nums [ i ] - nums [ n - i - 1 ]) * p + MOD ) % MOD ; p = ( p << 1 ) % MOD ; } return ( int ) ans ; } }Video Solution
Watch the video walkthrough for Sum of Subsequence Widths
Similar Questions
5 related questions you might find useful
Algorithms:
Patterns:
Data Structures:
Subscribe to Scale Engineer newsletter
Learn about System Design, Software Engineering, and interview experiences every week.
No spam, unsubscribe at any time.