记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
目录
- 12/16 1847. 最近的房间
- 12/17 3291. 形成目标字符串需要的最少字符串数 I
- 12/18 3292. 形成目标字符串需要的最少字符串数 II
- 12/19 3285. 找到稳定山的下标
- 12/20 3138. 同位字符串连接的最小长度
- 12/21 2545. 根据第 K 场考试的分数排序
- 12/22 1387. 将整数按权重排序
12/16 1847. 最近的房间
经房间按大小排序
先考虑minSize大的查询
将比minSize大的房间号放入ids序列中考虑
根据当前查询preferred_id 在ids中查找离他最近的两个id 比较差值大小
def closestRoom(rooms, queries):
"""
:type rooms: List[List[int]]
:type queries: List[List[int]]
:rtype: List[int]
"""
from sortedcontainers import SortedList
n=len(rooms)
rooms.sort(key=lambda x:x[1])
m=len(queries)
ans=[-1]*m
ids=SortedList()
j=n-1
for i in sorted(range(m),key=lambda i:-queries[i][1]):
pid,msize=queries[i]
while j>=0 and rooms[j][1]>=msize:
ids.add(rooms[j][0])
j-=1
diff=float("inf")
k = ids.bisect_left(pid)
if k:
diff = pid-ids[k-1]
ans[i]=ids[k-1]
if k<len(ids) and ids[k]-pid<diff:
ans[i]=ids[k]
return ans
12/17 3291. 形成目标字符串需要的最少字符串数 I
对于每个word 与target求出在结束在target[i]的前缀能够匹配的最长前缀back[i]
动态规划 dp[i]表示前i个字母需要最少字符串数
def minValidStrings(words, target):
"""
:type words: List[str]
:type target: str
:rtype: int
"""
def prefix(word,target):
s=word+"#"+target
n=len(s)
pi=[0]*n
for i in range(1,n):
j=pi[i-1]
while j>0 and s[i]!=s[j]:
j=pi[j-1]
if s[i]==s[j]:
j+=1
pi[i]=j
return pi
n=len(target)
back = [0]*n
for w in words:
pi = prefix(w, target)
m=len(w)
for i in range(n):
back[i]=max(back[i],pi[m+1+i])
dp=[0]+[10**9]*n
for i in range(n):
dp[i+1]=dp[i+1-back[i]]+1
if dp[i+1]>n:
return -1
return dp[n]
12/18 3292. 形成目标字符串需要的最少字符串数 II
对于每个word 与target求出在结束在target[i]的前缀能够匹配的最长前缀back[i]
动态规划 dp[i]表示前i个字母需要最少字符串数
def minValidStrings(words, target):
"""
:type words: List[str]
:type target: str
:rtype: int
"""
def prefix(word,target):
s=word+"#"+target
n=len(s)
pi=[0]*n
for i in range(1,n):
j=pi[i-1]
while j>0 and s[i]!=s[j]:
j=pi[j-1]
if s[i]==s[j]:
j+=1
pi[i]=j
return pi
n=len(target)
back = [0]*n
for w in words:
pi = prefix(w, target)
m=len(w)
for i in range(n):
back[i]=max(back[i],pi[m+1+i])
dp=[0]+[10**9]*n
for i in range(n):
dp[i+1]=dp[i+1-back[i]]+1
if dp[i+1]>n:
return -1
return dp[n]
12/19 3285. 找到稳定山的下标
从头依次遍历 找到所有大于threshold的山峰 右侧的就是稳定的
def stableMountains(height, threshold):
"""
:type height: List[int]
:type threshold: int
:rtype: List[int]
"""
ans=[]
for i in range(len(height)-1):
if height[i]>threshold:
ans.append(i+1)
return ans
12/20 3138. 同位字符串连接的最小长度
如果是k个字符串拼接而成 那么所有字符出现次数必定是k的倍数
从小到大枚举len(s)=n的因数 检查每一个子字符串字符出现次数是否相同
12/21 2545. 根据第 K 场考试的分数排序
提取第K列的数值排序
def sortTheStudents(score, k):
"""
:type score: List[List[int]]
:type k: int
:rtype: List[List[int]]
"""
ans=[]
l=[(score[i][k],i) for i in range(len(score))]
l.sort(reverse=True)
for _,i in l:
ans.append(score[i])
return ans
12/22 1387. 将整数按权重排序
记忆化搜索mem[x]记录x的权重
def getKth(lo, hi, k):
"""
:type lo: int
:type hi: int
:type k: int
:rtype: int
"""
mem={}
mem[1]=0
def find(x):
if x in mem:
return mem[x]
mem[x] = (find(x//2) if x%2==0 else find(3*x+1))+1
return mem[x]
l=list(range(lo,hi+1))
l.sort(key=lambda x:(find(x),x))
return l[k-1]