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

来源:互联网 发布:域名注册管理机构 编辑:程序博客网 时间:2024/06/05 10:24

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: TrueExplanation: You could modify the first 4 to 1 to get a non-decreasing array.

Example 2:

Input: [4,2,1]Output: FalseExplanation: 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: 3Explanation: 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: 1Explanation: 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[]数组里