Find both the minimum and maximum in array using less than 2 * (N - 2) comparisons

package _interview_question

/**
 * Good morning! Here's your coding interview problem for today.
This problem was asked by Facebook.
Given an array of numbers of length N, find both the minimum and maximum using less than 2 * (N - 2) comparisons.
 * */
class Solution18 {
    /*
    * Solution 1: linear search, 2*(n-2) comparisons in the worst case, 1+n-2 in best case, Time:O(n),Space:O(1);
    * 
    * Solution 2: Divide and Conquer, divide the array into two parts, 3*n/2-2 comparisons,
    * compare minimum and maximum in two parts to get the result of whole array,
    * Time:O(n), Space:O(n)
    * */
    fun findMinMax(array: IntArray): MinMax  {
        return solution2(array)
    }

    fun solution1(array: IntArray): MinMax {
        val n = array.size
        val minMax = MinMax()
        if (n == 1) {
            minMax.min = array[0]
            minMax.max = array[0]
            return minMax
        }
        //more than 2 numbers, init minimum and maximum
        if (array[0] > array[1]) {
            minMax.max = array[0]
            minMax.min = array[1]
        } else {
            minMax.max = array[1]
            minMax.min = array[0]
        }
        for (i in 2 until n) {
            if (array[i] > minMax.max) {
                minMax.max = array[i]
            } else if (array[i] < minMax.min) {
                minMax.min = array[i]
            }
        }
        return minMax
    }

    fun solution2(array: IntArray): MinMax {
        val l = 0
        val r = array.size - 1
        return getMinMax(array, l, r)
    }

    private fun getMinMax(array: IntArray, left: Int, right: Int): MinMax {
        val pair = MinMax()
        //only one element
        if (left == right) {
            pair.min = array[left]
            pair.max = array[left]
            return pair
        }
        //two element
        if (left + 1 == right) {
            if (array[left] > array[right]) {
                pair.min = array[right]
                pair.max = array[left]
            } else {
                pair.min = array[left]
                pair.max = array[right]
            }
            return pair
        }
        //if more than two element
        var pairLeft: MinMax? = null
        var pairRight: MinMax? = null
        val mid = left + (right - left) / 2
        pairLeft = getMinMax(array, left, mid)
        pairRight = getMinMax(array, mid + 1, right)
        //compare minimum of two parts
        if (pairLeft.min < pairRight.min) {
            pair.min = pairLeft.min
        } else {
            pair.min = pairRight.min
        }
        //compare maximum of two parts
        if (pairLeft.max > pairRight.max) {
            pair.max = pairLeft.max
        } else {
            pair.max = pairRight.max
        }
        return pair
    }
}

class MinMax {
    var min = Int.MAX_VALUE
    var max = Int.MIN_VALUE
}

 

posted @ 2021-01-13 11:50  johnny_zhao  阅读(80)  评论(0编辑  收藏  举报