力扣665題:非遞減數列
阿新 • • 發佈:2021-01-20
給你一個長度為 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%的使用者