Leetcode: 665. 非遞減數列

作者:Liao_Hong_XiDian
來源:CSDN
原文:https://blog.csdn.net/qq_23523409/article/details/85232742
版權聲明:本文爲博主原創文章,轉載請附上博文鏈接!

給定一個長度爲 n 的整數數組,你的任務是判斷在最多改變 1 個元素的情況下,該數組能否變成一個非遞減數列。

我們是這樣定義一個非遞減數列的: 對於數組中所有的 i (1 <= i < n),滿足 array[i] <= array[i + 1]。

示例 1:

輸入: [4,2,3]
輸出: True
解釋: 你可以通過把第一個4變成1來使得它成爲一個非遞減數列。
示例 2:

輸入: [4,2,1]
輸出: False
解釋: 你不能在只改變一個元素的情況下將其變爲非遞減數列。
說明:  n 的範圍爲 [1, 10,000]。

解題思路:

查找逆序對,逆序對的個數超過2,則必然return false;
逆序對只有一個,假設nums[pos]>nums[pos+1];在pos之前都是非逆序,pos+1之後也是非逆序。
可以修改nums[pos]的值,或者修改nums[pos+1]的值,使得整個序列滿足非逆序關係。
接下來只需考慮,這兩個數中的一個的修改範圍。如果修改nums[pos],那麼必須滿足以下:

nums[pos]>=nums[pos-1]
nums[pos]<=nums[pos+1]
很顯然,整個區間是[nums[pos-1],nums[pos+1]],閉區間。這樣一來,nums[pos-1],nums[pos],nums[pos+1]三個數構成非逆序,進一步得到整個數組是非逆序的。區間存在的前提條件是nums[pos-1]<=nums[pos+1]。

另外,如果修改nums[pos+1],那麼修改後的nums[pos+1]必須滿足以下:

nums[pos+1]>=nums[pos]。
nums[pos+1]<=nums[pos+2]
很顯然,整個區間是[nums[pos],nums[pos+2]],閉區間。這樣一來,nums[pos],nums[pos+1],nums[pos+2]構成非逆序,進一步得到整個數組是非逆序的。區間存在的前題條件是nums[pos]< nums[pos+2]

終上所述,如果要修改只有一個逆序對的數組,必須要滿足這兩個前提條件之一,注意數組溢出,換句話說,如果這兩個條件都不滿足,也就意味着修改一個數不可能使整個數組變成非逆序。到此就嚴格地說明了整個過程的可行性。

class Solution {
public:
        bool checkPossibility(vector<int>& nums) {
                int size = nums.size(), i, res = 0,pos=-1;
                for (i = 1; i <= size - 1; i++) {
                        if (nums[i - 1] > nums[i]) {
                                res++;
                                pos=i-1;
                        }
                        if (res > 1) return false;
                }
                if(pos==-1) return true;
                bool sgn1 = (pos+2<size&&nums[pos+2]<nums[pos]);
                bool sgn2 = (pos-1>=0&&nums[pos+1]<nums[pos-1]);
                return !(sgn1&&sgn2);
        }
};
static const int _ = []() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        cout.tie(nullptr);
        return 0;
}();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章