1. 程式人生 > 其它 >力扣665題:非遞減數列

力扣665題:非遞減數列

技術標籤:力扣演算法題演算法javaleetcode陣列

給你一個長度為 n 的整數陣列,請你判斷在 最多 改變 1 個元素的情況下,該陣列能否變成一個非遞減數列。我們是這樣定義一個非遞減數列的: 對於陣列中所有的 i (0 <= i <= n-2),總滿足 nums[i] <= nums[i + 1]

示例 1:
輸入: nums = [4,2,3]
輸出: true
解釋: 你可以通過把第一個4變成1來使得它成為一個非遞減數列。
示例 2:
輸入: nums = [4,2,1]
輸出: false
解釋: 你不能在只改變一個元素的情況下將其變為非遞減數列

這個題力給的難度是簡單。

演算法思路:其實挺好想的,把所有情況考慮清楚之後就很好編碼了,題目樣例沒有給的特別全,所以要自己把剩下幾種情況分出來。
這裡借鑑一下評論區第一(作者:碼不停題)的思路,整理一下可以得到:

我們來看下面三個例子:
4,2,3
-1,4,2,3
2,3,3,2,4
我們通過分析上面三個例子可以發現,
當我們發現後面的數字小於前面的數字產生衝突後:
[1]有時候需要修改前面較大的數字(比如前兩個例子需要修改4),
[2]有時候卻要修改後面較小的那個數字(比如前第三個例子需要修改2),
判斷修改哪個數字其實跟再前面一個數的大小有關係。
當再前面的數不存在時:
比如例子1,4前面沒有數字了,我們直接修改前面

的數字為當前的數字2即可。
當再前面的數字存在時:
①再前面的數小於當前數時,比如例子2,-1小於2,我們需要修改前面的數字4為當前數字2;
②再前面的數大於當前數,比如例子3,3大於2,我們需要修改當前數2為前面的數3

為了更好的理解裡面的邏輯關係,我將一些可以合併的if語句拆開來了,可以更好的理解該題。

原始碼:時間複雜度O(n),空間複雜度O(1)。

class Solution {
    public boolean checkPossibility(int[] nums) {
        int count = 0;
        if(nums == null || nums.
length <= 1) return true; for (int i = 1; i < nums.length && count <= 1; i++) { //後面的數字大於等於前面的數字,就continue然後繼續迴圈 if(nums[i] >= nums[i-1]){ continue; }else{ //發生了衝突,計數器++,然後判斷到底修改哪一個位置的值(要麼就是前面的,要麼就是當前的) count++; //如果再前面的數字存在,然後再進行判斷再前面的數字跟當前數字的關係 if(i - 2 >= 0){ if(nums[i-2] > nums[i]){ nums[i] = nums[i-1]; }else{ nums[i-1] = nums[i]; } }else{ //如果再前面的數字不存在,直接修改前面的數字為當前的數字 nums[i-1] = nums[i]; } } } return count<=1 ? true : false; } }

執行用時:
1 ms ,在所有 Java 提交中擊敗了99.55%的使用者
記憶體消耗:
39.7 MB, 在所有 Java 提交中擊敗了70.77%的使用者