2021-2-7 Leetcode每日刷题

2021-2-7 Leetcode每日刷题

题目

给你一个长度为 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
解释: 你不能在只改变一个元素的情况下将其变为非递减数列。

说明:

1 <= n <= 10 ^ 4
-10 ^ 5 <= nums[i] <= 10 ^ 5

我的思路

class Solution:
    def checkPossibility(self, nums: List[int]) -> bool:
        n = len(nums)
        check_list = []
        for i in range(0,n-1):
            if nums[i]>nums[i+1]:
                check_list.append(i)
        if len(check_list) == 0:  #如果没有则直接返回true
            return True
        elif len(check_list)>=2:  #如果有两个数都大于后一位则不可能递减
            return False
        else:
            num = check_list[0]
            raw_num1 = nums[num]
            raw_num2 = nums[num+1]
            for index in range(num,num+2):#测试前后两个值
                nums[num] = raw_num1      #把修改后的值还原
                nums[num+1] = raw_num2
                for k in range(min(nums)-n,max(nums)+n):   #测试这一个数为多少值的时候可以构成递减
                    flag = 0
                    nums[index] = k
                    for i in range(0,n-1):
                        if nums[i]>nums[i+1]:
                            #print((i,i+1),(nums[i],nums[i+1]))
                            flag = 1
                            break
                    if flag == 0:    #只有当所有数字都满足的时候返回true
                        return True                
        return False

提交结果:
2021-2-7 Leetcode每日刷题_第1张图片

参考思路

首先明确最多只能有一个i满足nums[i]>nums[i+1],而这两个值都是待修改的。其次,修改之后检查nums是否变成非递减数列。

我们可以将 nums[i] 修改成小于或等于nums[i+1] 的数,但由于还需要保证 nums[i] 不小于它之前的数,nums[i] 越大越好,所以将 nums[i] 修改成 nums[i+1] 是最佳的;同理,对于nums[i+1],修改成nums[i] 是最佳的。

class Solution:
    
    def is_sorted(self,nums):
        for i in range(0,len(nums)-1):
            if nums[i] > nums[i+1]:
                return False
        return True
    
    def checkPossibility(self, nums: List[int]) -> bool:
        n = len(nums)
        for i in range(0,n-1):
            x = nums[i]
            y = nums[i+1]
            if x > y:
                nums[i] = y
                if self.is_sorted(nums):
                    return True
                else:
                    nums[i] = x
                    nums[i+1] = x
                    return self.is_sorted(nums)

        return True

提交结果:
2021-2-7 Leetcode每日刷题_第2张图片
优化
上面的代码多次遍历了nums 数组,能否只遍历一次呢?

修改nums[i] 为nums[i+1] 后,还需要保证 nums[i−1]≤nums[i] 仍然成立,即 nums[i−1]≤nums[i+1],若该不等式不成立则整个数组必然不是非递减的,则需要修改 nums[i+1] 为 nums[i]。修改完后,接着判断后续数字的大小关系。在遍历中统计nums[i]>nums[i+1] 的次数,若超过一次可以直接返回false。

class Solution:
    def checkPossibility(self, nums: List[int]) -> bool:
        n = len(nums)
        cnt = 0
        for i in range(0,n-1):
            x = nums[i]
            y = nums[i+1]
            if x > y:
                cnt+=1
                if cnt>1:
                    return False
                if i>0 and nums[i-1]>y:
                    nums[i+1] = x                   
        return True

2021-2-7 Leetcode每日刷题_第3张图片
复杂度分析:

时间复杂度:O(n),其中 n 是数组nums 的长度。

空间复杂度:O(1)。

你可能感兴趣的:(leetcode)