Leetcode 每日一题
题目链接:514. 自由之路
难度: 困难
解题思路: 这道题乍一看,可以选择用动态规划或者BFS来求解。本文使用BFS来进行解答。注意到题中有一个最小的到路径。所以我们可以加入优先队列进行优化,用这个路径花费来对BFS中的队列进行排序,路径长度越小越先出队列。但是这样做还是不够快。会卡在如下样例:
"xrrakuulnczywjs"
"jrlucwzakzussrlckyjjsuwkuarnaluxnyzcnrxxwruyr"
所以我们还需要进行优化。我们需要加入一个visit数组来记录从key的i位置到ring的j位置的最小值(最小花费)。若当前又计算到了这个节点并且这个值还大于等于最小值,我们就抛弃这点,不进入队列。
本题使用的优先队列有个自定义的priority 。 可以直接将当前的花费作为这个优先级。
题解:
import heapq
# 定义优先队列
class PQ:
def __init__(self):
self._queue = []
self._index = 0
def queue_push(self, item, priority):
heapq.heappush(self._queue, (priority, index, item)) # 自定义排序,当前花费越越靠后
self._index += 1
def queue_pop(self):
return heapq.heappop(self._queue)[-1]
def is_empty(self):
return len(self._queue) != 0
class Solution:
def findRotateSteps(self, ring: str, key: str) -> int:
lenr = len(ring)
lenk = len(key)
def bfs():
# [key到达的位置, ring到达的位置, 当前花费]
pq = PQ()
pq.queue_push([0, 0, 0], 1)
# visit数组表示从key的i位置到ring的j位置的最小值。大于等于最小值的不考虑
visit = [[] for i in range(lenk)]
for i in range(lenk):
for j in range(lenr):
visit[i].append(0x3f3f3f3f)
while pq.is_empty():
node = pq.queue_pop()
# print(node)
# 当前遍历到key的最后,找到结果了
if node[0] == lenk:
return node[-1]
# 顺时针
for i in range(node[1], lenr):
if ring[i] == key[node[0]]:
#print(node)
priority = node[2] + i - node[1] + 1
if visit[node[0]][i] <= priority:
continue
visit[node[0]][i] = priority
pq.queue_push([node[0] + 1, i, priority], priority)
for i in range(0, node[1]):
if ring[i] == key[node[0]]:
priority = node[2] + i + (lenr - node[1]) + 1
if visit[node[0]][i] <= priority:
continue
visit[node[0]][i] = priority
pq.queue_push([node[0] + 1, i, priority], priority)
# 逆时针
for i in reversed(range(0, node[1])):
if ring[i] == key[node[0]]:
priority = node[2] + node[1] - i + 1
if visit[node[0]][i] <= priority:
continue
visit[node[0]][i] = priority
pq.queue_push([node[0] + 1, i, priority], priority)
for i in reversed(range(node[1], lenr)):
if ring[i] == key[node[0]]:
priority = node[2] + node[1] + (lenr - i) + 1
if visit[node[0]][i] <= priority:
continue
visit[node[0]][i] = priority
pq.queue_push([node[0] + 1, i, priority], priority)
res = bfs()
return res