目录
100296. 两个字符串的排列差
原题链接
思路分析
签到题,两次遍历搞定
AC代码
class Solution:
def findPermutationDifference(self, s: str, t: str) -> int:
mp = dict()
res = 0
for i, x in enumerate(s):
mp[x] = i
for i, x in enumerate(t):
res += abs(i - mp[x])
return res
100274. 从魔法师身上吸取的最大能量
原题链接
从魔法师身上吸取的最大能量 - 力扣 (LeetCode) 竞赛
思路分析
记忆化搜索
dfs(0)代表从0出发的最大能量,记忆化剪枝保证每个结点只走一次
时间复杂度O(n)
AC代码
class Solution:
def maximumEnergy(self, energy: List[int], k: int) -> int:
n = len(energy)
@cache
def dfs(x: int) -> int:
if x >= n:
return 0
return energy[x] + dfs(x + k)
return max(dfs(i) for i in range(n))
100281. 矩阵中的最大得分
原题链接
思路分析
典中典网格上递推,为了拼手速还是用的记忆化搜索
不过注意起点特判,可以在递归函数里面多加个bool参数
时间复杂度O(n^2)
AC代码
class Solution:
def maxScore(self, g: List[List[int]]) -> int:
m, n = len(g), len(g[0])
@cache
def dfs(x: int, y: int, lim: bool):
if x >= m or y >= n:
return 0
ret = -inf if lim else 0
if x + 1 < m:
ret = max(ret, g[x + 1][y] - g[x][y] + dfs(x + 1, y, False))
if y + 1 < n:
ret = max(ret, g[x][y + 1] - g[x][y] + dfs(x, y + 1, False))
return ret
return max(dfs(i, j, True) for j in range(n) for i in range(m))
100312. 找出分数最低的排列
原题链接
思路分析
看得出数据很弱啊,全排列+最优性剪枝就过了
就是全排列的暴搜,然后如果当前已经比最优解更差了就剪枝
时间复杂度:阶乘级别带剪枝的就不分析了
2024.5.1214:30
回看这道题发现就是状压dp求哈密顿回路板子题,而且起点一定是0,任何解可以轮转到0为起点
那么时间复杂度就是O(2^n * n)
AC代码
暴力
class Solution:
def findPermutation(self, nums: list[int]) -> list[int]:
n = len(nums)
mi = n * n
ret = []
path = []
st = set()
def dfs(res: int, s: int) -> None:
nonlocal mi, path, ret, st
# print(path, s, mi, res)
if s >= mi:
return
if (not res) and s + abs(path[-1] - nums[path[0]]) < mi:
mi = s + abs(path[-1] - nums[path[0]])
ret = path.copy()
# print(ret, s)
return
for i in range(n):
if not (i in st):
path.append(i)
st.add(i)
t = 0 if res == n else abs(nums[path[-1]] - path[-2])
dfs(res - 1, s + t)
path.pop()
st.remove(i)
dfs(n, 0)
return ret
状压dp
class Solution:
def findPermutation(self, nums: List[int]) -> List[int]:
n = len(nums)
g = [[0] * n for _ in range(n)]
for i in range(n):
for j in range(n):
g[i][j] = abs(i - nums[j])
f = [[inf] * n for _ in range(1 << n)]
ans = [["" + chr(ord('a') + n) * n] * n for _ in range(1 << n)]
f[1][0] = 0
ans[1][0] = "a"
for i in range(1, 1 << n):
if i & 1:
for j in range(n):
if i >> j & 1:
for k in range(n):
if i >> k & 1:
t = f[i ^ (1 << j)][k] + g[k][j]
s = ans[i ^ (1 << j)][k] + chr(ord('a') + j)
if t < f[i][j]:
f[i][j] = t
ans[i][j] = s
elif t == f[i][j] and s < ans[i][j]:
ans[i][j] = s
mi = inf
ret = str(n) * n
for i in range(1, n):
t = f[(1 << n) - 1][i] + g[i][0]
if t < mi:
mi = f[(1 << n) - 1][i] + g[i][0]
ret = ans[(1 << n) - 1][i]
elif t == mi and ans[(1 << n) - 1][i] < ret:
ret = ans[(1 << n) - 1][i]
return [ord(x) - ord('a') for x in ret]