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)的空间复杂度