Monday, August 10, 2015

minimal middle unsorted part of array

Find the minimal middle unsorted part of array which if sorted would make the array sorted.

The array consists of 3 parts left, middle, right. Initially left is the increasing sequence from beginning and right is the decreasing sequence from end. The left and right parts shrink till the following condition is met.
end(left) <= min(middle) && max(middle) <= start(right)
//example
  l        r
134558-58-4889
  |455-58-8|

min:4 max:8

 l   r
123-2
 |2-3|

min:2, max:3

l      r
 4-32-1
|1-23-4|

min:1, max:4
// assume a is increasing
(a):
    // left
    left = leftindex(a)
    // right
    right = rightindex(a)
    // return if already sorted
    if left > right:
        return null, null
    // min, max
    min, max = minmax(a, left, right)
    // shrink left, right
    left, right = shrink(a, left, right, min, max)
    // return
    return left+1, right-1

leftindex(a):
    left = 0
    while left+1 < a.length && a[left] <= a[left+1]:
        left++
    return left

rightindex(a):
    right = a.length-1
    while right-1 >= 0 && a[right-1] <= a[right]:
        right--
    return right

minmax(a, start, end):
    min = max = a[start]
    for i = start, i <= end, i++:
        if a[i] < min:
            min = a[i]
        if a[i] > max:
            max = a[i]
    return min, max

shrink(a, left, right, min, max):
    while left >= 0 && a[left] > min:
        left--
    while right < a.length && a[right] < max:
        right++
    return left, right
[Hat tip to ctci]

No comments:

Post a Comment