Max Sum of At Most Two Non-Overlapping Intervals

Last Updated : 12 Nov, 2025

Given an array interval[] , where each element represents the following three values

  • startTime – the time when the interval begins
  • endTime – the time when the interval ends
  • value – the value associated with this interval

Find the maximum sum of values by selecting at most two intervals that do not overlap.

Example: 

Input: interval[] = [[1, 3, 2], [4, 5, 2], [2, 4, 3]]
Output: 4
Explanation: Select interval 1 and 2 (as third interval is overlapping). Therefore, maximum value is 2 + 2 = 4.

Input: interval[] = [[1, 3, 2], [4, 5, 2], [1, 5, 5]]
Output: 5
Explanation: As intervals 1 and 2 are non-overlapping but their value will be 2 + 2 = 4. So, instead of 1 and 2, only 3 can be selected with a value of 5.

[Naive Approach] - O(n2) Time and O(1) Space

For each interval (or pair of intervals), we calculate the sum of their values only if they do not overlap and keep track of the maximum sum found so far. We also consider the case where a single interval alone provides the maximum value.

[Expected Approach]Using Priority Queue - O(n x logn) Time and O(n) Space

This problem can be solved with the help of a priority queue. To solve this problem, follow the below steps:

  1. Sort the given array interval w.r.t. startTime. If startTime of two intervals are the same then sort it on the basis of endTime.
  2. Store the pair of {endTime, value} in the priority queue ordered on the basis of endTime.
  3. Traverse the given array and calculate the maximum value for all events whose endTime is smaller than the startTime of the present interval and store it in variable max.
  4. Now, update the ans, after each traversal as, ans= Math.max(ans, max + interval[i][2]).
  5. Return ans as the final answer to this problem.

 Below is the implementation of the above approach

C++
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

int maxTwoIntervals(vector<vector<int> >& interval)
{
    // Sorting the given array
    // on the basis of startTime
    sort(interval.begin(), interval.end(),
         [](vector<int>& a, vector<int>& b) {
             return (a[0] == b[0]) ? a[1] < b[1]
                                   : a[0] < b[0];
         });

    priority_queue<vector<int>, vector<vector<int>>, greater<vector<int>>> pq;

    int ma = 0;
    int ans = 0;

    for (auto e : interval) {
        while (!pq.empty()) {

            // If endTime from priority
            // queue is greater
            // than startTime of
            // traversing interval
            // then break the loop
            if (pq.top()[0] >= e[0])
                break;
            vector<int> qu = pq.top();
            pq.pop();

            // Updating max variable
            ma = max(ma, qu[1]);
        }

        // Update maximum answer with 
        // non-overlapping intervals
        ans = max(ans, ma + e[2]);
        pq.push({ e[1], e[2] });
    }

    return ans;
}

int main()
{
    vector<vector<int>> interval
        = { { 1, 3, 2 }, { 4, 5, 2 }, { 1, 5, 5 } };
    int maxValue = maxTwoIntervals(interval);
    cout << maxValue;
    return 0;
}
Java
import java.util.Arrays;
import java.util.PriorityQueue;
class GFG {

    public static int maxTwoIntervals(int[][] interval)
    {
        // Sorting the given array
        // on the basis of startTime
        Arrays.sort(interval,
                    (a, b)
                        -> (a[0] == b[0]) ? a[1] - b[1]
                                          : a[0] - b[0]);

        PriorityQueue<int[]> pq
            = new PriorityQueue<>((a, b) -> a[0] - b[0]);

        int max = 0;
        int ans = 0;

        for (int[] e : interval) {
            while (!pq.isEmpty()) {

                // If endTime from priority
                // queue is greater
                // than startTime of
                // traversing interval
                // then break the loop
                if (pq.peek()[0] >= e[0])
                    break;
                int[] qu = pq.remove();

                // Updating max variable
                max = Math.max(max, qu[1]);
            }

            // Update maximum answer with 
            // non-overlapping intervals
            ans = Math.max(ans, max + e[2]);
            pq.add(new int[] { e[1], e[2] });
        }

        return ans;
    }
    
        public static void main(String[] args)
    {
        int[][] interval
            = { { 1, 3, 2 }, { 4, 5, 2 }, { 1, 5, 5 } };
        int maxValue = maxTwoIntervals(interval);
        System.out.println(maxValue);
    }
}
Python
from queue import PriorityQueue
def maxTwoIntervals(interval):
    # Sorting the given array
    # on the basis of startTime
    interval.sort()

    pq = PriorityQueue()

    ma = 0;
    ans = 0

    # Traversing the given array
    for e in interval:
        while not pq.empty():

            # If endTime from priority
            # queue is greater
            # than startTime of
            # traversing interval
            # then break the loop
            if (pq.queue[0][0] >= e[0]):
                break;
            qu = pq.get();

            # Updating max variable
            ma = max(ma, qu[1]);

        # Update maximum answer with
        # non-overlapping intervals
        ans = max(ans, ma + e[2]);
        pq.put([ e[1], e[2] ]);

    return ans;

if __name__=='__main__':

    interval = [ [ 1, 3, 2 ], [ 4, 5, 2 ], [ 1, 5, 5 ] ];
    
    maxValue = maxTwoIntervals(interval);
    print(maxValue);
C#
using System;
using System.Linq;
using System.Collections.Generic;

class GFG
{
  public static int maxTwoIntervals(int[][] interval)
  {
    // Sorting the given array
    // on the basis of startTime
    var sorted = interval.OrderBy(a => a[0]).ThenBy(a => a[1]);
    interval = sorted.ToArray();

    SortedSet<int[]> pq = new SortedSet<int[]>(Comparer<int[]>.Create((a, b) =>
      a[0] == b[0] ? a[1].CompareTo(b[1]) : a[0].CompareTo(b[0])));

    int max = 0;
    int ans = 0;

    // Traversing the given array
    foreach (int[] e in interval) {
      while (pq.Count > 0) {

        // If endTime from priority queue is greater
        // than startTime of traversing 
        // interval then break the loop
        if (pq.First()[0] >= e[0])
          break;

        int[] qu = pq.First();
        pq.Remove(qu);

        // Updating max variable
        max = Math.Max(max, qu[1]);
      }

      // Updating ans variable
      ans = Math.Max(ans, max + e[2]);

      pq.Add(new int[] { e[1], e[2] });
    }

    return ans;
  }
   public static void Main(string[] args)
  {
    int[][] interval = new int[][] {
      new int[] { 1, 3, 2 },
      new int[] { 4, 5, 2 },
      new int[] { 1, 5, 5 }
    };
    int maxValue = maxTwoIntervals(interval);
    Console.WriteLine(maxValue);
  }
}
JavaScript
function maxTwoIntervals(interval) {
    // Sorting the given array
    // on the basis of startTime
    interval.sort((a, b) => {
        if (a[0] === b[0]) {
            return a[1] - b[1];
        }
        return a[0] - b[0];
    });

    let pq = [];
    
    let ma = 0;
    let ans = 0;

    for (let e of interval) {
        while (pq.length > 0) {

            // If endTime from priority
            // queue is greater
            // than startTime of
            // traversing interval
            // then break the loop
            if (pq[0][0] >= e[0])
                break;
            let qu = pq.shift();

            // Updating max variable
            ma = Math.max(ma, qu[1]);
        }

        // Update maximum answer with 
        //non-overlapping intervals
        ans = Math.max(ans, ma + e[2]);
        pq.unshift([e[1], e[2]]);
        pq.sort((a, b) => b[0] - a[0]);
    }

    return ans;
}

    let interval = [[1, 3, 2], [4, 5, 2], [1, 5, 5]];
    let maxValue = maxTwoIntervals(interval);
    console.log(maxValue);

Output
5
Comment