为了保持算法能力,每天一道必刷题
1.至少有 K 个重复字符的最长子串
这道题要我们找出字符串中每个字符出现次数都不小于k,说明得是
单调数列
有两种方法:两次遍历和一次遍历:
两次遍历:分别进行递减数列和递增数列的判断,然后将两者or起来,可以判断是否是单调序列
一次遍历:使用两个值纪录上升或下降,如果单调序列必有一个值是True,如果都是False说明不是单调序列
2俄罗斯套娃信封问题
这道题的主要思想需要找到两个维度的最小递增序列,在计算最长递增序列可以使用两种方法,一种是使用动态规划进二重循环,之后计算其中的最大值,因为这是一个二维递增,可以将其转换为1维问题,即将第二维变为递减序列,只要前面的值小于后面的值,说明他们的第一维不相同
class Solution:
def maxEnvelopes(self, envelopes: List[List[int]]) -> int:
• if(len(envelopes)==0):
• return 0
• envelopes.sort(key=lambda x:(x[0],-x[1])) #关键词
• temp = envelopes[0]
• dp = [1]*len(envelopes) #dp数组含义为第i个信封所能有的尔罗斯套娃信封
• for i in range(len(envelopes)):
• for j in range(i): #二层循环
• if(envelopes[i][1]>envelopes[j][1]):
• dp[i] = max(dp[j]+1,dp[i])
• return max(dp)
3,下一个更大元素 II
因为是要在每个数组的附近找到一个最大的数,于是递减的数可以不用去考虑,而构造一个单调栈(也就是从栈顶到栈底是单调递减的,这样保证栈中的元素不会作为各自的元素)
class Solution:
def nextGreaterElements(self, nums: List[int]) -> List[int]:
#也就是说当遇到单调序列的时候就存储,如果遇到了比他大的就把所有栈中的东西放出来全部将其设为此时的数
value = nums
N = len(value)
answer = [-1 for i in range(N)] #全部初始化为-1
stack = [] #构造一个栈
for i in range(0,2*N-1): #也就是找到
index = i%N #也就是除以这个len
while(stack and value[index]>value[stack[-1]]):
answer[stack.pop()] = value[index] #把答案给变出来
stack.append(index) #首先把定义为这个值的数组全部改变之后
return answer
4分割回文串
这个题目首先题解错题意了,这个题目需要我们找到所有的分割方案,我首先以为的是要找到所有的的回文串个数,因为需要分割出来的字符串全是回文串,于是可以从0开始遍历起来,然后依次进行回溯,如果不成功就直接断掉,
还有一个判断是否是回文串的好方法,使用动态规划,构建一个二维数组dp[i][j]代表着i到j是否是回文串
class Solution(object):
def partition(self, s):
• self.isPalindrome = lambda s : s == s[::-1]
• res = []
• self.backtrack(s, res, [])
• return res
•
def backtrack(self, s, res, path):
• if not s:
• res.append(path)
• return
• for i in range(1, len(s) + 1): #注意起始和结束位置
• if self.isPalindrome(s[:i]):
• self.backtrack(s[i:], res, path + [s[:i]])
\