题目连接:LeetCode 1574. 删除最短的子数组使剩余数组有序
题意:
给你一个整数数组 arr ,请你删除一个子数组(可以为空),使得 arr 中剩下的元素是 非递减 的。
一个子数组指的是原数组中连续的一个子序列。
请你返回满足题目要求的最短子数组的长度。
示例 1:
输入:arr = [1,2,3,10,4,2,3,5]
输出:3
解释:我们需要删除的最短子数组是 [10,4,2] ,长度为 3 。剩余元素形成非递减数组 [1,2,3,3,5] 。
另一个正确的解为删除子数组 [3,10,4] 。
解题思路:
双指针,找出 前面的递增序列, 和后面的递增序列
然后如果前面的小于后面的, ans = max(ans, 前面的长度+后面的长度),最后返回 总长度减去 ans
class Solution {
/**
* @param Integer[] $arr
* @return Integer
*/
function findLengthOfShortestSubarray($arr) {
$a = array();
array_push($a, $arr[0]);
$n = count($arr);
$ans = 0; $f = 0;
for($i = 1; $i < $n; $i++) {
if($arr[$i] >= $a[$i-1]) {
array_push($a, $arr[$i]); // 前面的递增序列
} else {
$f = 1; // 如果需要删除子数组
break;
}
}
$ans = $i;
if($f == 1) {
$b = array(); $k = 0;
$b[0] = $arr[$n-1];
for($j = $n-2; $j >= $i; $j--) {
if($arr[$j] <= $b[$k]) {
$k++; array_push($b, $arr[$j]); // 后面的递增序列
} else {
break;
}
}
$b = array_reverse($b);
$i1 = 0; $j1 = 0;
$ans = max(count($a), count($b)); // 答案为前面的子序列长度或后面的
while($i1 < $i && $j1 < count($b)) {
if($a[$i1] <= $b[$j1]) {
$ans = max($ans, count($b) - $j1 + $i1 + 1); // 更新答案
$i1++;
}
else {
$j1++;
}
}
}
return $n - $ans;
}
}