Leetcode665 (Array) Non-decreasing Array +Leetcode674 Longest Continuous Increasing Subsequence

Given an array with n integers, your task is to check if it could become non-decreasing by modifying at most 1 element.

We define an array is non-decreasing if array[i] <= array[i + 1] holds for every i (1 <= i < n).

Example 1:

Input: [4,2,3]
Output: True
Explanation: You could modify the first 4 to 1 to get a non-decreasing array.

Example 2:

Input: [4,2,1]
Output: False
Explanation: You can't get a non-decreasing array by modify at most one element.

Note: The n belongs to [1, 10,000].

这个题不难,但是要考虑完全所有的情况。

两个Example让我觉得判断nums[i]>nums[i+1],则记录逆序的变量cnt(=0)+1。最后cnt==1 return True  else return False

这种简单粗暴的想法忽略了这种情况:

[3,4,2,3]

cnt==1,因为4>2,想要把4变成1,但是第一个3却大于1,所以还是False。

所以要记录逆序数4发生的角标(位置,index),判断index-1和index+1两个数的相对大小

我的AC Solution:

class Solution(object):
    def checkPossibility(self, nums):
        """
        :type nums: List[int]
        :rtype: bool
        """
        cnt=0
        reverse_index=0
        if len(nums)<=2:
            return True
        
        for i in range(0,len(nums)-1):
            if nums[i]>nums[i+1]:            
                cnt=cnt+1
                reverse_index=i
        
        #as for last two
        # if nums[len(nums)-2]>nums[len(nums)-1]:
        #     cnt=cnt+1
        
        if cnt==0:
            return True
        elif cnt==1:
            if reverse_index  == 0 or reverse_index==(len(nums)-2): # [1,2,4,5,3] 数组的倒数第二个数发生逆序
                return True
            elif nums[reverse_index-1]<=nums[reverse_index+1]: #[2,7,2,5]
                return True
            elif nums[reverse_index]<=nums[reverse_index+2]:#[2,3,3,2,4]
                return True
            else: 
                return False
        else:
            return False
           



受leetcode推荐继续刷674,延续上题思路AC出来了。

Given an unsorted array of integers, find the length of longest continuousincreasing subsequence.

Example 1:

Input: [1,3,5,4,7]
Output: 3
Explanation: The longest continuous increasing subsequence is [1,3,5], its length is 3. 
Even though [1,3,5,7] is also an increasing subsequence, it's not a continuous one where 5 and 7 are separated by 4. 

Example 2:

Input: [2,2,2,2,2]
Output: 1
Explanation: The longest continuous increasing subsequence is [2], its length is 1. 

Note: Length of the array will not exceed 10,000.

我原创的解法: 

时间复杂度:O(n)

空间复杂度:O(n) 

如果nums是[2,2,2,2,2]那么要新开辟一个reverse_points数组存储这n个相等的数,所以说是O(n)

class Solution(object):
    def findLengthOfLCIS(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        reverse_points = [0]    
        maximum = 1
        for i in range(0, len(nums) - 1):
            if nums[i] >= nums[i + 1]:
                reverse_points.append(i + 1)
                maximum = max(len(nums[reverse_points[-2]:reverse_points[-1]]), maximum)


        if len(reverse_points) == 1: 
            # 只有初始赋的一个0,证明这是一个纯递增(内不含相等值)序列
            # 也就是说上面的for循环没有添加新的index到reverse_points里
            maximum = len(nums)
        elif (reverse_points[-1] != (len(nums) - 1)):
            # 如果存储陡落位置的index不是倒数第一个数的话,证明最后一段是递增序列
            #并且结尾的index没有添加到reverse_points里
            maximum = max(len(nums[reverse_points[-1]:]), maximum)
        return maximum
        

本题一些值得思考的测试用例:

nums=[1,3,5,4,6,7,8,2,3]
nums=[1,3,5,7]
nums=[1,3,5,4,2,3,4,5]
nums=[1,3,5,4,2,3,4,5]
nums=[2,2,2,2,2,2]
nums=[1,1,2]
 
本题我绕了好大弯,因为我没有好好看example,[2,2,2,2,2,2]这种情况的最长子序列长度是1,我看到了但我没有思考,可以类比[1,1,2]这种情况的答案应该是2.
因为连续相等的值并不累加在最长子序列长度中。
 
所以说我一开始把 nums[i] > nums[i+1]与nums[i] ==nums[i+1]分开写,真是绕了好大的圈子

解题思路:

还是找陡落的地方的index,不过这次不是记录i了,为了方便求len()运算,存储的是index+1。

把陡落的地方的index+1放到reverse_points数组里,对于reverse_points数组里的每一段求长度,与最大值比较,留较大者。

注意最后的if -else 很重要,完善了逻辑。


更简单的解法二,比解法一在空间复杂度上进行了优化:

时间复杂度:O(n)

空间复杂度:O(1)

思路:记录当前递增子串的长度,与maximum做比较

class Solution(object):
    def findLengthOfLCIS(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        
        if len(nums)==0: 
            return 0
       
        maximum=1#为[2,2,2,2,2]这种情况考虑
        temp_length=1

        for i in range(0,len(nums)-1):
            if nums[i+1]>nums[i]:
                temp_length=temp_length+1
                maximum = max(maximum, temp_length)
            else:
                temp_length=1

        return  maximum

解法三 动态规划:

时间复杂度:O(n)

空间复杂度:O(n) ,因为 新开辟一个dp数组

class Solution(object):
    def findLengthOfLCIS(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        
        if len(nums)==0:
            return 0

        dp=[None]*len(nums)#记录到该位置的Longest Continuous Increasing Subsequence
        maximum=1
        dp[0]=1 #给dp[0]赋初始值,因为后面也没机会赋了
        # temp_length=1

        for i in range(0,len(nums)-1):
            if nums[i+1]>nums[i]:
                #temp_length=temp_length+1
                dp[i+1]=dp[i]+1
                #maximum = max(maximum, temp_length)
                maximum = max(maximum, dp[i+1])
            else:
                #temp_length=1
                dp[i+1]=1
        return  maximum

该解法是根据解法二改编而来,区别在于把解法二的temp_length记录在dp[]数组里

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值