记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
目录
-
-
- [1/26 1200. 最小绝对差](#1/26 1200. 最小绝对差)
- [1/27 3650. 边反转的最小路径总成本](#1/27 3650. 边反转的最小路径总成本)
- [1/28 3651. 带传送的最小路径成本](#1/28 3651. 带传送的最小路径成本)
- [1/29 2976. 转换字符串的最小成本 I](#1/29 2976. 转换字符串的最小成本 I)
- [1/30 2977. 转换字符串的最小成本 II](#1/30 2977. 转换字符串的最小成本 II)
- [1/31 744. 寻找比目标字母大的最小字母](#1/31 744. 寻找比目标字母大的最小字母)
- [2/1 3010. 将数组分成最小总代价的子数组 I](#2/1 3010. 将数组分成最小总代价的子数组 I)
-
1/26 1200. 最小绝对差
从小到大排序
一次计算相邻两个元素差
记录最小绝对差 和响应顺序
python
def minimumAbsDifference(arr):
"""
:type arr: List[int]
:rtype: List[List[int]]
"""
arr.sort()
ans = []
cur = float('inf')
for i in range(1,len(arr)):
if arr[i]-arr[i-1]<cur:
cur = arr[i]-arr[i-1]
ans = [[arr[i-1],arr[i]]]
elif arr[i]-arr[i-1]==cur:
ans.append([arr[i-1],arr[i]])
return ans
1/27 3650. 边反转的最小路径总成本
将每条边x,y,w 和它的反转边y,x,2w加入
python
def minCost(n, edges):
"""
:type n: int
:type edges: List[List[int]]
:rtype: int
"""
import heapq
g=[[] for _ in range(n)]
for x,y,w in edges:
g[x].append((y,w))
g[y].append((x,2*w))
d=[float("inf")]*n
v=[False]*n
d[0]=0
l=[(0,0)]
while l:
cur,x = heapq.heappop(l)
if x==n-1:
return cur
if v[x]:
continue
v[x]=True
for y,w in g[x]:
new=cur+w
if new<d[y]:
d[y]=new
heapq.heappush(l, (new,y))
return -1
1/28 3651. 带传送的最小路径成本
动归
cost[t][i][j]表示从i,j出发到终点传送t次的最小成本
t依赖t-1 外部循环 省略该维度
1.不使用传送
cost[i][j]=min(cost[i+1][j]+grid[i+1][j],cost[i][j+1]+grid[i][j+1])
2.传送
cost[i][j]=min(所有grid[x][y]<=grid[i][j]的cost[x][y])
将(i,j)根据grid的值升序排列 mincost记录从小grid开始的最小成本
之后的cost[i][j]=mincost
python
def minCost(grid, k):
"""
:type grid: List[List[int]]
:type k: int
:rtype: int
"""
m,n=len(grid),len(grid[0])
points=[(i,j) for i in range(m) for j in range(n)]
points.sort(key=lambda x:grid[x[0]][x[1]])
costs=[[float('inf')]*n for _ in range(m)]
for t in range(k+1):
mincost=float('inf')
j=0
for i in range(len(points)):
mincost=min(mincost,costs[points[i][0]][points[i][1]])
if i+1<len(points) and grid[points[i][0]][points[i][1]]==grid[points[i+1][0]][points[i+1][1]]:
i+=1
continue
for r in range(j,i+1):
costs[points[r][0]][points[r][1]]=mincost
j=i+1
for i in range(m-1,-1,-1):
for j in range(n-1,-1,-1):
if i==m-1 and j==n-1:
costs[i][j]=0
continue
if i!=m-1:
costs[i][j]=min(costs[i][j],costs[i+1][j]+grid[i+1][j])
if j!=n-1:
costs[i][j]=min(costs[i][j],costs[i][j+1]+grid[i][j+1])
return costs[0][0]
1/29 2976. 转换字符串的最小成本 I
floyd
预处理26个字母间转换的最小成本
python
def minimumCost(source, target, original, changed, cost):
"""
:type source: str
:type target: str
:type original: List[str]
:type changed: List[str]
:type cost: List[int]
:rtype: int
"""
c=[[float('inf')]*26 for _ in range(26)]
for i in range(26):
c[i][i]=0
for x,y,z in zip(original,changed,cost):
ix=ord(x)-ord('a')
iy=ord(y)-ord('a')
c[ix][iy]=min(c[ix][iy],z)
for k in range(26):
for i in range(26):
for j in range(26):
c[i][j]=min(c[i][j],c[i][k]+c[k][j])
ans=0
for x,y in zip(source,target):
ix=ord(x)-ord('a')
iy=ord(y)-ord('a')
if c[ix][iy]==float('inf'):
return -1
ans+=c[ix][iy]
return ans
1/30 2977. 转换字符串的最小成本 II
python
def minimumCost(source, target, original, changed, cost):
"""
:type source: str
:type target: str
:type original: List[str]
:type changed: List[str]
:type cost: List[int]
:rtype: int
"""
class Trie:
def __init__(self):
self.child = [None] * 26
self.id = -1
def add(node, word, index):
for ch in word:
i = ord(ch) - ord("a")
if node.child[i] is None:
node.child[i] = Trie()
node = node.child[i]
if node.id == -1:
index[0] += 1
node.id = index[0]
return node.id
def update(x, y):
if x == -1 or y < x:
return y
return x
n,m=len(source),len(original)
root=Trie()
p=[-1]
g=[[float('inf')]*(2*m) for _ in range(2*m)]
for i in range(2*m):
g[i][i]=0
for i in range(m):
x=add(root,original[i],p)
y=add(root,changed[i],p)
g[x][y]=min(g[x][y],cost[i])
for k in range(p[0]+1):
for i in range(p[0]+1):
for j in range(p[0]+1):
g[i][j]=min(g[i][j],g[i][k]+g[k][j])
f=[-1]*n
for j in range(n):
if j>0 and f[j-1]==-1:
continue
base=0 if j==0 else f[j-1]
if source[j]==target[j]:
f[j]=update(f[j], base)
u=v=root
for i in range(j,n):
u=u.child[ord(source[i])-ord("a")]
v=v.child[ord(target[i])-ord("a")]
if u is None or v is None:
break
if u.id!=-1 and v.id!=-1 and g[u.id][v.id]!=float("inf"):
f[i]=update(f[i],base+g[u.id][v.id])
return f[n-1]
1/31 744. 寻找比目标字母大的最小字母
字符列表经过排序 第一个字符为最小 记录第一个字符
从小到大依次判断是否大于target 如果第一次找到大于target的字符 为最小字母返回
如果一直到最后都没找到 说明要从头循环 第一个字符为最小
python
def nextGreatestLetter(letters, target):
"""
:type letters: List[str]
:type target: str
:rtype: str
"""
ans = letters[0]
for c in letters:
if c>target:
return c
return ans
2/1 3010. 将数组分成最小总代价的子数组 I
数组第一个数必在代价中
找出之后最小的两个数值即可
python
def minimumCost(nums):
"""
:type nums: List[int]
:rtype: int
"""
a,b=float("inf"),float("inf")
for num in nums[1:]:
if num<a:
a,b=num,a
elif num<b:
b=num
return nums[0]+a+b