132. Palindrome Partitioning II
https://leetcode.com/problems/palindrome-partitioning-ii/description/
相当于计算最少步数的经典模板,不过cut数是子串数 - 1。
ahhbcz's solution
代码如下:
class Solution:
def minCut(self, s):
"""
:type s: str
:rtype: int
"""
n = len(s)
res = list(range(-1, n))
for i in range(n):
for (l, r) in [(i, i), (i, i+1)]:
while l >= 0 and r < n and s[l] == s[r]:
res[r+1] = min(res[r+1], res[l] + 1)
l -= 1
r += 1
return res[-1]
139. Word Break
https://leetcode.com/problems/word-break/description/
这道题依然符合模板公式。
优化一:
将wordDict转换成set,让查询时间复杂度变为O(1).
优化二:
如果切割出的字符串比wordDict中最长的字符串还长,就不用查询了。
代码如下:
class Solution:
def wordBreak(self, s, wordDict):
"""
:type s: str
:type wordDict: List[str]
:rtype: bool
"""
res = [True]
max_len = max(map(len, wordDict + ['']))
wordDict = set(wordDict)
for i in range(1, len(s) + 1):
res += any([res[j] and s[j:i] in wordDict for j in range(max(0, i - max_len), i)]),
return res[-1]
300. Longest Increasing Subsequence
https://leetcode.com/problems/longest-increasing-subsequence/description/
下面的解法巧妙的利用二分查找将时间复杂度降低到O(nlogn).
Python explain the O(nlogn) solution step by step
代码如下:
class Solution:
def lengthOfLIS(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
def binarySearch(nums, target):
left, right = 0, len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] == target:
return mid
if nums[mid] < target:
left = mid + 1
else:
right = mid - 1
return left
res = []
for num in nums:
index = binarySearch(res, num)
if index == len(res):
res.append(num)
else:
res[index] = num
return len(res)
下面解法为动态规划模板解法,时间复杂度为O(n2),遇到最后一个全为1的testcase会超时。仅供参考。
代码如下:
class Solution:
def lengthOfLIS(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
max_value = 0
m = len(nums)
res = [1 for x in range(m)]
for i in range(m):
for j in range(i):
if nums[j] < nums[i]:
res[i] = max(res[i], res[j] + 1)
max_value = max(max_value, res[i])
return max_value