记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
遍历s,t每个起始位置 遍历长度k
判断两个子串差别字符diff是否为1
def countSubstrings(s, t):
"""
:type s: str
:type t: str
:rtype: int
"""
ans = 0
for i in range(len(s)):
for j in range(len(t)):
diff = 0
k = 0
while i+k<len(s) and j+k<len(t):
if s[i+k]!=t[j+k]:
diff +=1
if diff==1:
ans +=1
elif diff>1:
break
k+=1
return ans
将两个字符串直接相连 就是一个公共超序列 但是并不是最短的
为了超序列最短 我们要尽可能去除相同的序列
及求最长公共子序列LCS
使用动态规划dp[i][j]来代表str1[:i],str2[:j]的LCS长度
n,m = len(str1),len(str2)
那么最短公共超序列长度为n+m-dp[n][m]
下一步是还原处最长公共子序列
从后往前倒退 记录每一个关键节点在loc
从前往后遍历关键节点 将两个关键节点之间非关键的字符加入答案中即可
例如:
str1=“zabcz”
str2=“zdefz”
关键节点为(0,0),(4,4)
对于str1非关键位置为[1,3]将这部分加入
同样str2也是[1,3] 最后可以得到zabcdefz
def shortestCommonSupersequence(str1, str2):
"""
:type str1: str
:type str2: str
:rtype: str
"""
n,m = len(str1),len(str2)
dp = [[0]*(m+1) for _ in range(n+1)]
for i in range(1,n+1):
for j in range(1,m+1):
if str1[i-1]==str2[j-1]:
dp[i][j] =dp[i-1][j-1]+1
else:
dp[i][j] = max(dp[i-1][j],dp[i][j-1])
li,lj = n,m
loc = []
while li>0:
if str1[li-1]==str2[lj-1]:
loc.append([li-1,lj-1])
li-=1
lj-=1
else:
if dp[li-1][lj]==dp[li][lj]:
li-=1
else:
lj-=1
ans =""
li,lj = -1,-1
for i,j in loc[::-1]:
if li+1<i:
ans += str1[li+1:i]
if lj+1<j:
ans+= str2[lj+1:j]
ans += str1[i]
li,lj = i,j
if li+1<n:
ans += str1[li+1:]
if lj+1<m:
ans += str2[lj+1:]
return ans
a,e,i,o,u标记为4,3,2,1,0
及前面的数值不能小于后面的数值
递归(cur,num) cur为当前可以选的最大值 num为还需要多少个数
def countVowelStrings(n):
"""
:type n: int
:rtype: int
"""
mem={}
def check(cur,num):
ans = 0
if num==0:
return 1
if (cur,num) in mem:
return mem[(cur,num)]
for v in range(cur+1):
ans += check(v,num-1)
mem[(cur,num)] = ans
return ans
return check(4,n)
只需要考虑横坐标位置
去重从小到大排序 寻找相邻点的最大值
def maxWidthOfVerticalArea(points):
"""
:type points: List[List[int]]
:rtype: int
"""
l = list(set([p[0] for p in points]))
l.sort()
ans = 0
for i in range(1,len(l)):
ans = max(ans,l[i]-l[i-1])
return ans
确定第一个数 i 判断nums[i]+diff,nums[i]+2*diff是否在数组中
def arithmeticTriplets(nums, diff):
"""
:type nums: List[int]
:type diff: int
:rtype: int
"""
s = set(nums)
n = len(nums)
ans =0
for i in range(n-2):
if nums[i]+diff in s and nums[i]+2*diff in s:
ans +=1
return ans
先判断是否为邮箱
按邮箱处理方式处理邮箱
若是电话号码 则提取有多少数字 按照规则处理
def maskPII(s):
"""
:type s: str
:rtype: str
"""
loc = s.find('@')
if loc>=0:
return (s[0]+"*"*5+s[loc-1:]).lower()
s = "".join(i for i in s if i.isdigit())
if len(s)==10:
return "***-***-"+s[-4:]
else:
return "+"+"*"*(len(s)-10)+"-***-***-"+s[-4:]
假设dp[i][j]为顶点i…j的凸j-i+1边型的最低分
动态规划 遍历其中可能的k值
将dp[i][j]可分为
dp[i][k] i,k,j三角形 dp[k][j]
def minScoreTriangulation(values):
"""
:type values: List[int]
:rtype: int
"""
n = len(values)
mem={}
def dp(i,j):
if (i,j) in mem:
return mem[(i,j)]
if i+2>j:
return 0
if i+2==j:
return values[i]*values[i+1]*values[j]
ans =min((values[i] * values[k] * values[j] + dp(i, k) + dp(k, j)) for k in range(i + 1, j))
mem[(i,j)] = ans
return ans
return dp(0,n-1)