leetcode
leetcode 551 ~ 600
非递减数列

非递减数列

难度:

标签:

题目描述

代码结果

运行时间: 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+1]可以解决当前逆序对问题而不会对后续元素产生负面影响。然而,如果nums[i+1]本来就大于nums[i+2],这种修改会增加新的逆序对。因此,这种策略可能并不总是最佳选择,而应视上下文和具体数组情况具体分析。
🦆
算法在处理数组的两端元素时是否有特殊的边界条件考虑?比如数组的第一个或最后一个元素在逆序时的处理方式。
算法确实对数组的两端元素有特殊考虑。特别是当逆序对出现在数组的开头时(i=0),此时nums[i-1]不存在,因此不需要检查nums[i+1] < nums[i-1]的条件。在这种情况下,可以直接修改nums[i]为nums[i+1]或者保持不变,因为没有前一个元素与之比较。对于数组末端的元素,由于遍历到n-2停止,所以不需要特别处理最后一个元素。
🦆
在实际修改数组元素时,如何确定是将nums[i+1]调整为nums[i],而不是将nums[i]减小至nums[i+1]?
决定是否将nums[i+1]调整为nums[i]或将nums[i]减小至nums[i+1]取决于nums[i-1]和nums[i+1]的关系。如果nums[i+1]小于nums[i-1],则将nums[i+1]调整为nums[i]可能是更安全的选择,因为这样做不会影响前面的逆序状态。若没有这种情况,减少nums[i]至nums[i+1]可能是更好的选择,因为它可能减少对后续元素的潜在影响。这种决定需要根据数组的具体情况灵活处理。
🦆
此算法中提及的‘尽可能不影响后面的元素’的原则是如何在代码中体现的?是否有可能存在更优的修改策略?
此原则通过仅在绝对必要时修改元素来体现,且修改尝试最小化对数组其余部分的影响。例如,当nums[i+1] < nums[i-1]时,选择修改nums[i+1]而不是nums[i],是为了避免对前面元素造成影响。尽管如此,可能存在更优的策略,例如,通过先进行一次扫描确定最小的修改点,或考虑使用动态规划解决多个修改点的场景。这些策略可能在特定情况下提供更优的结果,但也可能导致算法复杂度上升。

相关问题