算法:在数组中找出所有这样的数,它比它前面的数都大,比它后面的数都小

Ques:在数组中找出这样的数,它比它前面的数都大,比它后面的数都小


构造一个“查找表” Min[n];对应位置上Min[i],存放了原数组A[i]位置往后这一部分的最小值。

一个变量Max,保存了在遍历A[n]时,遇到的最大值。

遍历A[n],如果 A[i]>=Max (比前面的数都大),并且 A[i] <= Min[i] (比后面的数都小),输出A[i]。

 

$arrOrigin = [21,11,45,56,9,66,77,89,78,68,100,120,111];
$ret = findItem($arrOrigin);
//print_r($ret);
function findItem($arrOrigin){
    $arrMin = []; 
    $len = count($arrOrigin);
    $intMax = $arrOrigin[0];
    $arrMin[$len-1] = $arrOrigin[$len-1];
    $ret = [];
    for($i=$len-2; $i>=0; $i--){//构造查找表
        $arrMin[$i] = $arrOrigin[$i] < $arrMin[$i+1] ? $arrOrigin[$i] : $arrMin[$i+1];
    }
    for($i=0; $i<$len; $i++){
        if($arrOrigin[$i] >= $intMax && $arrOrigin[$i] <= $arrMin[$i]){
            $ret[] = $arrOrigin[$i];
        }
        if($intMax < $arrOrigin[$i]){
            $intMax = $arrOrigin[$i];
        }
    }
    return $ret;
}


O(N)的时间复杂度和O(N)的空间复杂度

 

另一种解法:

在数组中,找到最小值的地址(指针、索引)MinIndex,则

1、如果MinIndex 指向最后一个元素,则不符合要求;

2、如果MinIndex 指向第一个元素,则第一个元素满足要求,输出。

3、如果MinIndex 指向中间的某个元素,则对后半部分,重复进行上面的过程。

在上述算法中,需要设置一变量Max,保存MinIndex 前面一部分的最大值。

$arrOrigin = [21,11,45,56,9,66,77,89,78,68,100,120,111];
$ret = findItem($arrOrigin);
print_r($ret);
function findMin(&$arrOrigin, $intL, $intR){
    $intLen = count($arrOrigin);
    $intMinKey = $intL;
    for($i=$intL+1; $i<=$intR; $i++){//查找最小值
        $intMinKey = $arrOrigin[$i] < $arrOrigin[$intMinKey] ? $i : $intMinKey;
    }
    return $intMinKey;
}

function findMax(&$arrOrigin, $intL, $intR){
    $intLen = count($arrOrigin);
    $intMaxKey = $intL;
    for($i=$intL+1; $i<=$intR; $i++){//查找最大值
        $intMaxKey = $arrOrigin[$i] > $arrOrigin[$intMaxKey] ? $i : $intMaxKey;
    }
    return $intMaxKey;
}

function findItem($arrOrigin){
    $ret = [];
    $intLen = count($arrOrigin);
    if($intLen == 0){
        return $ret;
    }
    $intL = 0;
    $intR = $intLen-1;
    if($intL == $intR){
        return $arrOrigin;
    }
    $intMax = PHP_INT_MIN;
    while($intL <= $intR){
        $intMinKey = findMin($arrOrigin, $intL, $intR); // 找到最小值的索引
        $intMaxKey = findMax($arrOrigin, $intL, $intMinKey); // 找到MinIndex 前面一部分的最大值
        if($arrOrigin[$intMaxKey] > $intMax){
            $intMax = $arrOrigin[$intMaxKey];
        }

if($intMinKey == $intL && $arrOrigin[$intMinKey] >= $intMax){// Index 指向第一个元素,如果它比Max大,则符合要求 $ret[] = $arrOrigin[$intMinKey]; } $intL = $intMinKey+1; } return $ret; }

O(1)的时间复杂度和O(N)的空间复杂度

posted @ 2020-02-28 10:49  cfYu  阅读(1317)  评论(0编辑  收藏  举报