记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
解题思路:1.
dp[0][0]=true
dp[i][j]表示s的前i个字符与p的前j个字符是否匹配
初始化p为* 与前面满足的状态一直
如果p[j-1]的位置为*:
1.p退一位满足 及代表空 dp[i][j-1]
2.s退一位满足 及代表字符串 dp[i-1][j]
3.p,s各退一位满足 及代表这个字符 dp[i-1][j-1]
若p的位置不为 需同时满足:
1.p,s这个位置的字符相等 或者 p的位置为?
2.同时前一个位置需要满足条件 true
最终结果为dp[len(s)][len§] 此方法耗时较大
2.先遍历s i,j分别记录s,p的位置 start用来记录的位置 m用来记录用代替若干个字符后s的位置
如果s[i]p[j]或p[j]’?‘则这个位置满足 i,j同时+1
如果p[j]==’’ 记录的位置start 和s当前的位置m p的位置+1
如果 存在及start有位置的值 那么将p挪回到后的位置start+1 s的位置往后移i=m+1
若都不满足则返回失败
遍历完s后,查看p的位置j 略过*的位置
如果j已经在p的末尾则说明匹配成功
def isMatch(s, p):
"""
:type s: str
:type p: str
:rtype: bool
"""
dp = [[False for i in range(len(p)+1)] for j in range(len(s)+1)]
dp[0][0]=True
for i in range(1,len(p)+1):
if p[i-1]=='*':
dp[0][i] = dp[0][i-1]
for i in range(1,len(s)+1):
for j in range(1,len(p)+1):
if p[j-1]=='*':
dp[i][j] = dp[i-1][j] or dp[i][j-1] or dp[i-1][j-1]
else:
dp[i][j] = (s[i-1] == p[j-1] or p[j-1] == '?') and dp[i-1][j-1]
return dp[len(s)][len(p)]
def isMatch2(s, p):
"""
:type s: str
:type p: str
:rtype: bool
"""
i,j=0,0
start = -1
m=0
while i<len(s):
if j<len(p) and (s[i]==p[j] or p[j]=='?'):
i+=1
j+=1
elif j<len(p) and p[j]=='*':
start = j
j+=1
m = i
elif start!=-1:
j = start+1
m +=1
i = m
else:
return False
while j<len(p):
if p[j]=='*':
j+=1
else:
break
return j==len(p)
解题思路:题目说明一定可以跳到队末 要次数最少
找到调到队尾的最靠前的一个点 将队尾移到这个点 跳动次数+1 pos记录当前的地址
反复寻找
begin用来记录重新开始寻找的点
如果开头是1则直接进行跳跃 次数+1 begin+1 及略过开头若干个1
def jump(nums):
"""
:type nums: List[int]
:rtype: int
"""
begin = 0
pos = 0
num = 0
l = len(nums)
if l<2:
return num
while True:
while nums[pos]==1:
pos+=1
if pos==l-1:
break
num+=1
begin = pos
while pos+nums[pos]<l-1:
pos+=1
num +=1
if pos==begin or pos==l-1:
break
l = pos+1
pos = begin
return num
解题思路:初始化每人一个糖
从1开始遍历队列 与前一个位置比较如果 分数比前一个位置大 那么糖的数量为前一个位置+1
倒序队列和糖果list 再一次从1开始遍历队列 相当于倒的在比较一次
此时如果分数比前一个位置大 那么糖的数量为max(当前数量,前一个位置+1)
最后求糖果list的和
def candy(ratings):
"""
:type ratings: List[int]
:rtype: int
"""
l = len(ratings)
if l==0:
return 0
candys =[1]*l
for i in range(1,l):
if ratings[i]>ratings[i-1]:
candys[i] = candys[i-1]+1
candys.reverse()
ratings.reverse()
for i in range(1,l):
if ratings[i]>ratings[i-1]:
candys[i] = max(candys[i],candys[i-1]+1)
return sum(candys)
解题思路:findNum()在一个数组中取n个数的子序列 顺序不变 但是序列最大 参考402.remove-k-digits
mergeNum() 将两个list在不改变其内部顺序的条件下 合并成一个list 并使得list最大
将问题分解为若干个小问题
问题 从nums1,nums2中取k个数 组合成一个最大list 并且从n1,n2中取得数顺序不变:
分解为:
1.从nums1中取i个数,得到最大序列tmp1
2.从nums2中取k-i个数,得到最大序列tmp2
3.合并tmp1,tmp2得到最大序列tmp
ps:
注意i,k-i与nums的大小
在merge两个list时遇到一样的 要继续比较后面的值
def maxNumber(nums1, nums2, k):
"""
:type nums1: List[int]
:type nums2: List[int]
:type k: int
:rtype: List[int]
"""
def findNum(num,n):
l = len(num)
if l==0:
return []
k = l-n
stack = []
move = k
stack.append(num[0])
for i in num[1:]:
while i>stack[-1] and move>0:
stack.pop()
move -=1
if len(stack)==0:
break
stack.append(i)
while move>0:
stack.pop()
move-=1
return stack
def mergeNum(l1,l2):
ret = []
tmp1 = l1[:]
tmp2 = l2[:]
tmp1.append(-1)
tmp2.append(-1)
i,j=0,0
while (i<len(l1) or j<len(l2)):
if tmp1[i]>tmp2[j]:
ret.append(tmp1[i])
i+=1
elif tmp1[i]<tmp2[j]:
ret.append(tmp2[j])
j+=1
else:
tmpi = min(i+1,len(l1))
tmpj = min(j+1,len(l2))
while tmp1[tmpi]==tmp2[tmpj]:
tmpi = min(tmpi+1,len(l1))
tmpj = min(tmpj+1,len(l2))
if tmpi==len(l1) and tmpj==len(l2):
break
if tmp1[tmpi]>tmp2[tmpj]:
ret.append(tmp1[i])
i+=1
else:
ret.append(tmp2[j])
j+=1
return ret