Leetcode: 665. 非遞減數列

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

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

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

示例 1:ide

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

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

解題思路:blog

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

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]。get

另外,若是修改nums[pos+1],那麼修改後的nums[pos+1]必須知足如下:it

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]io

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

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;
}();
相關文章
相關標籤/搜索