Minimum length subarray of an unsorted array sorting which results in complete sorted array

Given an unsorted array of integers, find the shortest subarray, which upon sorting will result in complete sorted array.
Example -  
Input : 1 4 7 5 10 18 17 26 30 45 50 62
Output: 5


Please try solving this problem before jumping on the solution

Click to learn




Subscribe for more updates



Algorithm/Insights

Icorrect Approach:
On the first look, it appears that if you perform following steps, then it will suffice:
1. From the beginning of the array, move to element in the array up to which the elements are sorted i.e. where array[i] > array[i+1]. Set startIndex = i.
2. From the end of the array, move to the element up to which the elements are sorted in reverse order i.e. where array[j-1] > array[j]. Set endIndex = j.

Consider the array given in problem section:

So this approach works for this array.
But this is not the correct approach as can be seen from the following example. Consider the modified array:
(replace 5 by 3 and 18 by 48)

On sorting the sub array from startIndex to endIndex:

Clearly the resultant array is not sorted. Now let us look at the correct approach.

Correct Approach:
1. From the beginning of the array, move to element in the array up to which the elements are sorted i.e. where array[i] > array[i+1]. Set startIndex = i.
2. From the end of the array, move to the element up to which the elements are sorted in reverse order i.e. where array[j-1] > array[j]. Set endIndex = j.
3. Find the minimum and maximum elements in the subarray from startIndex to endIndex.
4. Search the sorted array from 0 to startIndex to find the index at which minimum element will be in sorted array say, minIndex.
5. Search the sorted array from endIndex to end of array to find the index at which maximum element will be in sorted array say, maxIndex.
6. Sub array between minIndex to maxIndex is the required subarray. Print the subarray.

Note: If minIndex and maxElement found in steps 4 and 5 are same, then the array is already sorted.

Example:
Consider the array:


Step 1: From the beginning of the array, move to element in the array up to which the elements are sorted i.e. where array[i] > array[i+1]. Set startIndex = i.


Step 2. From the end of the array, move to the element up to which the elements are sorted in reverse order i.e. where array[j-1] > array[j]. Set endIndex = j.


Step 3. Find the minimum and maximum element in the subarray from startIndex to endIndex.


Step 4. Search the sorted array from 0 to startIndex to find the index at which minimum element will be in sorted array say, minIndex.


Step 5. Search the sorted array from endIndex to end of array to find the index at which maximum element will be in sorted array say, maxIndex.


Step 6. Sub array between minIndex to maxIndex is the required subarray.


Algorithm Visualization




Code Snippet

			
package com.ideserve.questions.saurabh;

import java.util.Arrays;

/**
 * <b>IDeserve <br>
 * <a href="https://www.youtube.com/c/IDeserve">https://www.youtube.com/c/IDeserve</a>
 * Find subarray of an unsorted array, sorting which will result in complete sorted array
 * 
 * @author Saurabh
 */
public class MaxLengthSubarray {

	public static void main(String[] args) {
		int[] array1 = {1, 4, 7, 3, 10, 48, 17, 26, 30, 45, 50, 62};
		printMaxLengthSubarray(array1);

		int[] array2 = {1, 2, 3, 4, 5};
		printMaxLengthSubarray(array2);
		
		int[] array3 = {5, 4, 3, 2, 1};
		printMaxLengthSubarray(array3);
	}
	
	public static void printMaxLengthSubarray(int[] array) {
		
		int n = array.length;

		// From the beginning of the array, move to element in the array up to which the elements are sorted i.e. where array[i] > array[i+1]. Set startIndex = i.
		int startIndex = 0;
		for (int i = 0; i < n-1; i++) {
			if(array[i] > array[i+1]) {
				startIndex = i;
				break;
			}
		}

		// From the end of the array, move to the element up to which the elements are sorted in reverse order i.e. where array[j-1] > array[j]. Set endIndex = j.
		int endIndex = 0;
		for (int j = n-1; j > 0; j--) {
			if(array[j-1] > array[j]) {
				endIndex = j;
				break;
			}
		}

		// Find the minimum and maximum element in the sub array from startIndex to endIndex.
		int maxElement = array[startIndex];
		int minElement = array[startIndex];
		for (int i = startIndex+1; i <= endIndex; i++) {
			if(maxElement < array[i]) {
				maxElement = array[i];
			}
			if(minElement > array[i]) {
				minElement = array[i];
			}
		}
		
		// Search the sorted array from 0 to startIndex to find the index at which minimum element will be in sorted array say, minIndex.
		int minIndex = findMinIndex(array, minElement, startIndex);
		
		// Search the sorted array from endIndex to end of array to find the index at which maximum element will be in sorted array say, maxIndex.
		int maxIndex = findMaxIndex(array, maxElement, endIndex);

		// Sub array between minIndex to maxIndex is the required sub array.
		if(minIndex == maxIndex) {
			System.out.println("The array is already sorted.");
			return;
		}
		for (int i = minIndex; i <= maxIndex; i++) {
			System.out.print(array[i] + " ");
		}
		System.out.println();
	}

	private static int findMinIndex(int[] array, int minElement, int startIndex) {
		for(int i = 0; i < startIndex; i++) {
			if(minElement < array[i]) {
				return i;
			}
		}
		return startIndex;
	}
	
	private static int findMaxIndex(int[] array, int maxElement, int endIndex) {
		for(int i = array.length-1; i > endIndex; i--) {
			if(maxElement > array[i]) {
				return i;
			}
		}
		return endIndex;
	}

}
		

Order of the Algorithm

Time Complexity is O(n)
Space Complexity is O(1) auxiliary space


Contribution

  • Sincere thanks from IDeserve community to Saurabh Kumar for compiling current post.

    Saurabh Kumar

    Ninja Programmer