非递减数列
难度:
标签:
题目描述
代码结果
运行时间: 24 ms, 内存: 16.9 MB
// Java Stream solution
// 思路:
// 虽然 Stream 不太适合这种带有修改操作的题目,但我们仍可以利用 Stream 的一些方法
// 如 anyMatch 和 noneMatch 来判断是否存在非递减违反的情况
import java.util.stream.IntStream;
public class Solution {
public boolean checkPossibility(int[] nums) {
int count = (int) IntStream.range(0, nums.length - 1)
.filter(i -> nums[i] > nums[i + 1])
.count();
if (count > 1) return false;
for (int i = 0; i < nums.length - 1; i++) {
if (nums[i] > nums[i + 1]) {
if (i > 0 && nums[i - 1] > nums[i + 1]) {
nums[i + 1] = nums[i];
} else {
nums[i] = nums[i + 1];
}
}
}
return true;
}
}
解释
方法:
题解的核心思路是遍历数组,记录出现逆序对的次数。当遍历到第i个元素时,如果发现nums[i] > nums[i+1],即出现逆序对,此时增加计数器cnt。如果cnt超过1,则直接返回False,表示不能通过修改一个元素使数组变成非递减序列。如果是第一次遇到逆序,还需要检查nums[i+1]是否小于nums[i-1],如果是,为了尽可能不影响后面的元素,将nums[i+1]设置为nums[i]。这样可以减小后续修改的可能性,增加成为非递减序列的机会。
时间复杂度:
O(n)
空间复杂度:
O(1)
代码细节讲解
🦆
在判断nums[i] > nums[i+1]时,直接将nums[i+1]设置为nums[i]的操作是否可能引起后续其他元素的逆序问题?
▷🦆
算法在处理数组的两端元素时是否有特殊的边界条件考虑?比如数组的第一个或最后一个元素在逆序时的处理方式。
▷🦆
在实际修改数组元素时,如何确定是将nums[i+1]调整为nums[i],而不是将nums[i]减小至nums[i+1]?
▷🦆
此算法中提及的‘尽可能不影响后面的元素’的原则是如何在代码中体现的?是否有可能存在更优的修改策略?
▷