记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
目录
11/8 299. 猜数字游戏
逐位比较
如果相同则公牛数+1
如果不同 则在两个map中分别记录字符出现次数
奶牛数即为每个字符在两个map中的较小值
def getHint(secret, guess):
"""
:type secret: str
:type guess: str
:rtype: str
"""
from collections import defaultdict
n=len(secret)
smap = defaultdict(int)
gmap = defaultdict(int)
bulls = 0
for i in range(n):
if secret[i]==guess[i]:
bulls+=1
else:
smap[secret[i]] +=1
gmap[guess[i]] +=1
cows = sum([min(smap[str(i)],gmap[str(i)]) for i in range(10)])
ans = "{}A{}B".format(bulls,cows)
return ans
11/9 488. 祖玛游戏
函数clean用来做消球操作
手球hand 排个序
visited记录(board,hand)状态 防止重复考虑
BFS li存储当前考虑序列[board,hand,放置手球次数]
i,j代表在board[i]前放置第j个手球hand[j]
如果手球与上一次手球一样 则跳过 hand[j]==hand[j-1]
如果手球与上一个位置一样 也跳过放置的情况是一样的 hand[j]==board[i-1]
def findMinStep(board, hand):
"""
:type board: str
:type hand: str
:rtype: int
"""
def clean(s):
loc = 0
while loc<len(s):
num = 1
tmp = loc
while loc<len(s):
tmp+=1
if tmp==len(s):
break
if s[loc]==s[tmp]:
num+=1
else:
break
if num>2:
s = s[:loc]+s[tmp:]
loc = max(0,loc-1)
while loc>0:
if s[loc]==s[loc-1]:
loc = loc-1
else:
break
else:
loc+=1
return s
hand = "".join(sorted(hand))
li = [(board,hand,0)]
visited = set([(board,hand)])
while li:
curb,curh,step = li[0]
li = li[1:]
for i in range(len(curb)+1):
for j in range(len(curh)):
## 如果手中球和上一个颜色一样
if j>0 and curh[j]==curh[j-1]:
continue
##上一个位子的球与当前手中球颜色一样
if i>0 and curb[i-1]==curh[j]:
continue
nb = clean(curb[:i]+curh[j]+curb[i:])
nh = curh[:j]+curh[j+1:]
if not nb:
return step+1
if (nb,nh) not in visited:
li.append((nb,nh,step+1))
visited.add((nb,nh))
return -1
11/10 495. 提莫攻击
记录中毒结束时间finish
def findPoisonedDuration(timeSeries, duration):
"""
:type timeSeries: List[int]
:type duration: int
:rtype: int
"""
ans = 0
finish = -1
for t in timeSeries:
if t>finish:
ans +=duration
else:
ans += duration - (finish-t+1)
finish = t+duration-1
return ans
11/11 629. K个逆序对数组
有n个数字[1,n] 产生k个逆序对
dp[n][k]代表n个数字产生k个逆序对情况
考虑最大值n的位置
如果n放在第一位 会产生n-1个逆序对 剩下n-1个数需要产生k-(n-1)个逆序对
如果n放在第二位 会产生n-2个逆序对 剩下n-1个数需要产生k-(n-2)个逆序对
dp[n][k] = dp[n-1][k] + dp[n-1][k-1] + … + dp[n-1][k-(n-1)]
对于dp[n][k-1] = dp[n-1][k-1]+…+dp[n-1][k-(n-1)]+dp[n-1][k-1-(n-1)]
两式错位相减
dp[n][k]-dp[n][k-1] = dp[n-1][k]-dp[n-1][k-n] (k>=n)
=> dp[n][k] = dp[n][k]+dp[n-1][k] - dp[n-1][k-n](if k>=n)
只与n,n-1相关 可以压缩为一维数组
def kInversePairs(n, k):
"""
:type n: int
:type k: int
:rtype: int
"""
MOD = 10**9+7
dp = [1]+[0]*k
for i in range(2,n+1):
nextdp = [1]+[0]*k
for j in range(1,k+1):
nextdp[j] = (nextdp[j-1]+dp[j]-(dp[j-i] if j>=i else 0))%MOD
dp = nextdp
return dp[-1]
11/12 375. 猜数字大小 II
1.dp[i][j]代表在[i,j]范围内最少金额
i>=j时 dp[i][j]=0
对于在[i,j]中遍历每一种可能性k dp[i][j] = min(k+max(dp[i][k-1],dp[k+1][j]))
2.遍历每一种[i,j]长度
def getMoneyAmount1(n):
"""
:type n: int
:rtype: int
"""
dp = [[0]*(n+1) for _ in range(n+1)]
for i in range(n-1,0,-1):
for j in range(i+1,n+1):
dp[i][j] = i+dp[i+1][j]
for k in range(i,j):
dp[i][j] = min(k+max(dp[i][k-1],dp[k+1][j]),dp[i][j])
return dp[1][n]
def getMoneyAmount(n):
"""
:type n: int
:rtype: int
"""
dp = [[0]*(n+2) for _ in range(n+2)]
for l in range(2,n+1):
for i in range(1,n-l+2):
j = i+l-1
dp[i][j]=float('inf')
for k in range(i,j+1):
cur = max(dp[i][k-1],dp[k+1][j])+k
dp[i][j] = min(dp[i][j],cur)
return dp[1][n]
11/13 520. 检测大写字母
依次判断三个条件
全是大写;全是小写;首字母大写,后续小写
def detectCapitalUse(word):
"""
:type word: str
:rtype: bool
"""
if word==str.upper(word):
return True
if word==str.lower(word):
return True
if 'A'<=word[0]<='Z' and word[1:]==str.lower(word[1:]):
return True
return False
11/14 677. 键值映射
1.map中存放key-val映射关系 覆盖储存
得到前缀后 遍历所有key 如果前缀匹配 则将val累加
2.字典树
class MapSum1(object):
def __init__(self):
"""
Initialize your data structure here.
"""
self.dic = {}
def insert(self, key, val):
"""
:type key: str
:type val: int
:rtype: None
"""
self.dic[key]=val
def sum(self, prefix):
"""
:type prefix: str
:rtype: int
"""
ret = 0
for k in self.dic.keys():
if k.startswith(prefix):
ret+=self.dic[k]
return ret
class MapSum(object):
def __init__(self):
"""
Initialize your data structure here.
"""
self.dic = {}
def insert(self, key, val):
"""
:type key: str
:type val: int
:rtype: None
"""
dic = self.dic
for c in key:
if c not in dic:
dic[c]={}
dic=dic[c]
dic['end'] = val
def sum(self, prefix):
"""
:type prefix: str
:rtype: int
"""
ret = 0
dic = self.dic
print(dic)
for c in prefix:
if c not in dic:
return 0
else:
dic = dic[c]
l = [dic]
while l:
tmp = []
for m in l:
for k,v in m.items():
if k=='end':
ret +=v
else:
tmp.append(v)
l = tmp
return ret