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 continuous
increasing 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[]数组里