Leetcode Insert Interval problem solution

In the Leetcode Insert Interval problem solution You are given an array of non-overlapping intervals intervals where intervals[i] = [starti, endi] represent the start and the end of the ith interval and intervals is sorted in ascending order by starti. You are also given an interval newInterval = [start, end] that represents the start and end of another interval.

Insert newInterval into intervals such that intervals is still sorted in ascending order by starti and intervals still does not have any overlapping intervals (merge overlapping intervals if necessary).

Return intervals after the insertion.

Example 1:

Input: intervals = [[1,3],[6,9]], newInterval = [2,5]
Output: [[1,5],[6,9]]

Example 2:

Input: intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]
Output: [[1,2],[3,10],[12,16]]
Explanation: Because the new interval [4,8] overlaps with [3,5],[6,7],[8,10].

Constraints:

  • 0 <= intervals.length <= 104
  • intervals[i].length == 2
  • 0 <= starti <= endi <= 105
  • intervals is sorted by starti in ascending order.
  • newInterval.length == 2
  • 0 <= start <= end <= 105

Solution in C Programming


#define MAX( x, y ) ( (x) > (y) ) ? (x) : (y)
#define MIN( x, y ) ( (x) < (y) ) ? (x) : (y)

void swap( int *x, int *y ){

   if ( x != y ){
      *x ^= *y;
      *y ^= *x;
      *x ^= *y;
   }

}

int binarySearch( int **intervals, int intervalsSize, int target, bool startIdx ){

   int l = -1;
   int r = intervalsSize;

   while( l+1 < r ){

      int m = l + (r-l)/2;

      int middleValue = (startIdx) ? intervals[m][1] : intervals[m][0];

      if      ( middleValue < target ) l = m;
      else if ( middleValue > target ) r = m;
      else                          return m;
   }

   if (startIdx)  return r;
   else           return l;
}


void addInterval( int **array, int idx, int start, int end ){

   array[idx] = (int*)malloc(2*sizeof(int));
   array[idx][0] = start;
   array[idx][1] = end;

}

int** insert(int** intervals, int intervalsSize, int* intervalsColSize,
             int* newInterval, int newIntervalSize, int* returnSize, int** returnColumnSizes)
{

   int **returnArray = NULL;

// handle the case that intervalsSize is zero
   if ( intervalsSize == 0 ){

      *returnSize = 1;
      *returnColumnSizes = (int*)malloc(*returnSize*sizeof(int));

      for (int i=0;i<*returnSize;i++) (*returnColumnSizes)[i] = 2;

      returnArray    = (int**)calloc(1,sizeof(int*));

      addInterval( returnArray, 0, newInterval[0], newInterval[1] );

      return returnArray;
   }

// get the position of start/end of the newInterval
   int left  = binarySearch( intervals, intervalsSize, newInterval[0], true );
   int right = binarySearch( intervals, intervalsSize, newInterval[1], false);


// perform insertion
   if ( left == right+1 ){

//    initialize the returnArray
      *returnSize = intervalsSize+1;
      returnArray = (int**)calloc(*returnSize, sizeof(int*));

      swap( &left, &right );

      for( int i=0; i<*returnSize; i++ ){

         returnArray[i] = (int*)malloc(2*sizeof(int));

//       copy the left part of the intervals to returnArray
         if ( i < left +1 ){
           addInterval( returnArray, i, intervals[i][0], intervals[i][1] );
         }
//       insert newInterval into returnArray
         else if ( i ==  left+1 ){
           addInterval( returnArray, i,   newInterval[0],  newInterval[1] );
         }
//       copy the right part of the intervals to returnArray
         else{
           addInterval( returnArray, i, intervals[i-1][0], intervals[i-1][1] );
         }
      }

   }

// merge intervals
   else{

      int maxIdxLeftUnperturbedBin, minIdxRightUnperturbedBin, numPerturbedBins;

//    the maximum index of the unperturbed bins on the left perturbed region
      maxIdxLeftUnperturbedBin  = left-1;

//    the minimum index of the unperturbed bins on the right perturbed region
      minIdxRightUnperturbedBin = right+1;

//    the number of unperturbed intervals
      numPerturbedBins = minIdxRightUnperturbedBin-maxIdxLeftUnperturbedBin-1;

//    initialize the returnArray
      *returnSize = intervalsSize-numPerturbedBins+1;
      returnArray = (int**)calloc(*returnSize, sizeof(int*));

//    the start/end of the merged bin
      newInterval[0] = MIN( newInterval[0], intervals[left ][0] );
      newInterval[1] = MAX( newInterval[1], intervals[right][1] );


      for( int i=0;i<*returnSize;i++ ){

//       copy the left part of the intervals to returnArray
         if      ( i <= maxIdxLeftUnperturbedBin ){
            addInterval( returnArray, i, intervals[i][0], intervals[i][1] );
         }
//       copy the merged bin to returnArray
         else if ( i == maxIdxLeftUnperturbedBin+1 ){
            addInterval( returnArray, i, newInterval[0], newInterval[1] );
         }
//       copy the right part of the intervals to returnArray
         else{
            addInterval( returnArray, i, intervals[i+numPerturbedBins-1][0],
                                         intervals[i+numPerturbedBins-1][1] );
         }
      }
   }

// set returnColumnSizes
   *returnColumnSizes = (int*)malloc(*returnSize*sizeof(int));
   for (int i=0;i<*returnSize;i++) (*returnColumnSizes)[i] = 2;

   return returnArray;
}

Solution in C++ Programming

class Solution {
public:
   vector<vector<int>> insert(vector<vector<int>>& intervals, vector<int>& newInterval) {
        std::vector<std::vector<int>>res;
        for (int cur{0}; cur < intervals.size(); cur++) {
            int cstart {intervals[cur][0]};
            int cend {intervals[cur][1]};

            if (newInterval.size()) {
                    // Merge New node with previous node
                if (res.size() && (res.back()[1] >= newInterval[0])) {
                    res.back()[1] = std::max(res.back()[1], newInterval[1]);
                    newInterval.clear();
                }
                
                // Insert New Node
                if (newInterval[0] <= cstart) {
                    // New Node should be inserted as first Node
                    // or in between before current Node
                    if (newInterval[1] < cstart) {
                        res.push_back(newInterval);
                        newInterval.clear();
                    } else if (newInterval[1] >= cstart) {
                        res.push_back({newInterval[0], std::max(newInterval[1], cend)});
                        newInterval.clear();
                        continue;
                    }
                } else if (cend >= newInterval[0]) {
                    // merge new Node if possible
                    res.push_back({cstart, std::max(cend, newInterval[1])});
                    newInterval.clear();
                    continue;
                }
            }
            // There is no new node or new node can't be used
            if (res.size() && res.back()[1] >= cstart) {
                res.back()[1] = std::max(res.back()[1], cend);
                continue;
            }
            res.push_back(intervals[cur]);
        }
        if (newInterval.size())
            res.push_back(newInterval);
        return res;
    }
};

Solution in Java Programming

class Solution {
   public int[][] insert(int[][] intervals, int[] newInterval) {
        List<int[]> seq = new ArrayList<>(intervals.length);
        for (int[] i: intervals) {
            if (newInterval == null || i[1] < newInterval[0]) {
                seq.add(i);
            } else if (i[0] > newInterval[1]) {
                seq.add(newInterval);
                seq.add(i);
                newInterval = null;
            } else {
                newInterval[0] = Math.min(newInterval[0], i[0]);
                newInterval[1] = Math.max(newInterval[1], i[1]);
            }
        }
        if (newInterval != null) {
              seq.add(newInterval);
        }
        return seq.toArray(new int[seq.size()][2]);
   }
}

Solution in Python Programming

class Solution(object):
   def insert(self, intervals, newInterval):
      intervals.append(newInterval)
      intervals.sort(key=lambda x:x[0])
      l,r=intervals[0]
      res=[]
      for n in intervals[1:]:
        if (n[0]<l and n[1]<l) or (n[1]>r and n[0]>r):
            res.append([l,r])
            l,r=n
        
        else:
            r=max(r,n[1])
            l=min(l,n[0])
    
      res.append([l,r])
      return res

Solution in C# Programming

public class Solution {
    public int[][] Insert(int[][] intervals, int[] newInterval) {
        var n = intervals.Length;

        if (n == 0) {
            return new int[][] { newInterval };
        }

        var result = new List<int[]>();

        // 1. insert
        var isAdded = false;
        for (int i = 0; i < n; i++) {
            if (intervals[i][0] > newInterval[0]) {
                // first item larger than newInterval
                isAdded = true;
                result.Add(newInterval);
            }
            result.Add(intervals[i]);
        }

        // 1.1 tail?
        if (!isAdded) {
            result.Add(newInterval);
        }

        // 2. merge
        result = mergeIntervals(result);
        return result.ToArray();
    }

    private List<int[]> mergeIntervals(List<int[]> intervals) {
        var n = intervals.Count;
        if (n <= 1) return intervals;

        var result = new List<int[]>();
        result.Add(intervals[0]);

        for (int i = 1; i < n; i++) {
            var cur = intervals[i];
            var lastFromResult = result.Last();

            if (lastFromResult[1] >= cur[0]) {
                lastFromResult[1] = Math.Max(lastFromResult[1], cur[1]);
            } else {
                result.Add(cur);
            }
        }

        return result;
    }
}

Also read,

By Neha Singhal

Hi, my name is Neha singhal a software engineer and coder by profession. I like to solve coding problems that give me the power to write posts for this site.

Leave a Reply

Your email address will not be published. Required fields are marked *