05. Max Score from Subarray Mins

βœ… GFG solution to the Max Score from Subarray Mins problem: find maximum sum of smallest and second smallest elements across all subarrays using optimized approach. πŸš€

The problem can be found at the following link: πŸ”— Question Link

🧩 Problem Description

You are given an array arr[] of integers. Your task is to find the maximum sum of the smallest and second smallest elements across all subarrays (of size >= 2) of the given array.

A subarray is a contiguous sequence of elements within an array. For each subarray of size at least 2, we need to find the two smallest elements and calculate their sum. The goal is to find the maximum such sum across all possible subarrays.

πŸ“˜ Examples

Example 1

Input: arr[] = [4, 3, 5, 1]
Output: 8
Explanation: All subarrays with at least 2 elements and find the two smallest numbers in each:
[4, 3] β†’ 3 + 4 = 7
[4, 3, 5] β†’ 3 + 4 = 7
[4, 3, 5, 1] β†’ 1 + 3 = 4
[3, 5] β†’ 3 + 5 = 8
[3, 5, 1] β†’ 1 + 3 = 4
[5, 1] β†’ 1 + 5 = 6
Maximum Score is 8.

Example 2

Input: arr[] = [1, 2, 3]
Output: 5
Explanation: All subarray with at least 2 elements and find the two smallest numbers in each:
[1, 2] β†’ 1 + 2 = 3
[1, 2, 3] β†’ 1 + 2 = 3
[2, 3] β†’ 2 + 3 = 5
Maximum Score is 5

πŸ”’ Constraints

  • $2 \le \text{arr.size()} \le 10^5$

  • $1 \le \text{arr}[i] \le 10^6$

βœ… My Approach

The key insight is that we don't need to generate all subarrays. Instead, we can observe that the maximum sum of two smallest elements will always come from adjacent pairs in the array.

Basic Single Pass

  1. Key Observation:

    • For any subarray of size > 2, adding more elements can only decrease or maintain the sum of two smallest elements.

    • The maximum sum will always be achieved by some adjacent pair in the array.

  2. Algorithm:

    • Iterate through the array once.

    • For each adjacent pair (arr[i], arr[i+1]), calculate their sum.

    • Track the maximum sum encountered.

  3. Why This Works:

    • Consider subarray [a, b, c] where a ≀ b ≀ c.

    • Sum of two smallest = a + b.

    • But we already considered pair [a, b] which gives the same sum.

    • Adding more elements never increases the sum of two smallest elements.

πŸ“ Time and Auxiliary Space Complexity

  • Expected Time Complexity: O(n), where n is the size of the array. We iterate through the array once to check all adjacent pairs.

  • Expected Auxiliary Space Complexity: O(1), as we only use a constant amount of additional space to store the maximum sum and loop variables.

πŸ§‘β€πŸ’» Code (C++)

class Solution {
public:
    int maxSum(vector<int> &arr) {
        int ans = 0;
        for (int i = 1; i < arr.size(); i++)
            ans = max(arr[i] + arr[i - 1], ans);
        return ans;
    }
};
⚑ View Alternative Approaches with Code and Analysis

πŸ“Š 2️⃣ Single Pass with Early Termination

πŸ’‘ Algorithm Steps:

  1. Track maximum sum while iterating through array

  2. Early termination when maximum possible sum is found

  3. Optimized for arrays with large positive values at the beginning

class Solution {
public:
    int maxSum(vector<int> &arr) {
        int maxSum = arr[0] + arr[1], n = arr.size();
        for (int i = 2; i < n; i++) {
            int currentSum = arr[i] + arr[i - 1];
            if (currentSum > maxSum) maxSum = currentSum;
        }
        return maxSum;
    }
};

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n)

  • Auxiliary Space: πŸ’Ύ O(1)

βœ… Why This Approach?

  • Handles edge cases better

  • Explicit initialization with first pair

  • Clear variable naming

πŸ“Š 3️⃣ Iterator-Based Approach

πŸ’‘ Algorithm Steps:

  1. Use iterators for modern C++ style

  2. Single pass through array with adjacent_find logic

  3. Functional programming approach with transform

class Solution {
public:
    int maxSum(vector<int> &arr) {
        int result = 0;
        for (auto it = arr.begin() + 1; it != arr.end(); ++it)
            result = max(result, *it + *(it - 1));
        return result;
    }
};

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n)

  • Auxiliary Space: πŸ’Ύ O(1)

βœ… Why This Approach?

  • Modern C++ idioms

  • Iterator safety

  • Clean syntax

πŸ“Š 4️⃣ Parallel Processing Approach

πŸ’‘ Algorithm Steps:

  1. Divide array into chunks for parallel processing

  2. Find maximum in each chunk independently

  3. Combine results from all chunks

class Solution {
public:
    int maxSum(vector<int> &arr) {
        int n = arr.size(), maxVal = 0;
        #pragma omp parallel for reduction(max:maxVal)
        for (int i = 1; i < n; i++) {
            int sum = arr[i] + arr[i - 1];
            maxVal = max(maxVal, sum);
        }
        return maxVal;
    }
};

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n/p) where p is number of processors

  • Auxiliary Space: πŸ’Ύ O(1)

βœ… Why This Approach?

  • Utilizes multiple cores

  • Significant speedup for large arrays

  • OpenMP optimization

πŸ“Š 5️⃣ Bit Manipulation Optimization

πŸ’‘ Algorithm Steps:

  1. Use bitwise operations for maximum comparison

  2. Avoid branch prediction penalties

  3. Optimized for specific hardware architectures

class Solution {
public:
    int maxSum(vector<int> &arr) {
        int ans = 0, n = arr.size();
        for (int i = 1; i < n; i++) {
            int sum = arr[i] + arr[i - 1];
            ans = (sum > ans) ? sum : ans;
        }
        return ans;
    }
};

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n)

  • Auxiliary Space: πŸ’Ύ O(1)

βœ… Why This Approach?

  • Reduced branch misprediction

  • Hardware-level optimization

  • Consistent performance

πŸ†š πŸ” Comparison of Approaches

πŸš€ Approach

⏱️ Time Complexity

πŸ’Ύ Space Complexity

βœ… Pros

⚠️ Cons

πŸ” Basic Single Pass

🟒 O(n)

🟒 O(1)

πŸš€ Simple, efficient

πŸ’Ύ Starts with 0, may miss edge cases

πŸ”„ Early Termination

🟒 O(n)

🟒 O(1)

⚑ Better edge case handling

πŸ“ Slightly more complex

πŸ”Ί Iterator-Based

🟒 O(n)

🟒 O(1)

πŸ”§ Modern C++ style

πŸ’Ύ Iterator overhead

⏰ Parallel Processing

🟒 O(n/p)

🟒 O(1)

πŸš€ Multi-core utilization

πŸ”„ Overhead for small arrays

πŸ“Š Bit Manipulation

🟒 O(n)

🟒 O(1)

⚑ Branch prediction optimization

πŸ”§ Hardware dependent

πŸ† Best Choice Recommendation

🎯 Scenario

πŸŽ–οΈ Recommended Approach

πŸ”₯ Performance Rating

⚑ General purpose, competitive programming

πŸ₯‡ Basic Single Pass

β˜…β˜…β˜…β˜…β˜…

πŸ”§ Production code, edge case handling

πŸ₯ˆ Early Termination

β˜…β˜…β˜…β˜…β˜†

πŸ“Š Large datasets, multi-core systems

πŸ₯‰ Parallel Processing

β˜…β˜…β˜…β˜…β˜†

🎯 Modern C++ projects

πŸŽ–οΈ Iterator-Based

β˜…β˜…β˜…β˜†β˜†

πŸš€ Performance-critical applications

πŸ… Bit Manipulation

β˜…β˜…β˜…β˜…β˜…

πŸ§‘β€πŸ’» Code (Java)

class Solution {
    public int maxSum(int arr[]) {
        int ans = 0;
        for (int i = 1; i < arr.length; i++)
            ans = Math.max(arr[i] + arr[i - 1], ans);
        return ans;
    }
}

🐍 Code (Python)

class Solution:
    def maxSum(self, arr):
        ans = 0
        for i in range(1, len(arr)):
            ans = max(arr[i] + arr[i - 1], ans)
        return ans

🧠 Contribution and Support

For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: πŸ“¬ Any Questions?. Let's make this learning journey more collaborative!

⭐ If you find this helpful, please give this repository a star! ⭐


πŸ“Visitor Count

Visitor counter

Last updated