1. 信物传送
欢迎各位勇者来到力扣城,本次试炼主题为「信物传送」。
本次试炼场地设有若干传送带,matrix[i][j]
表示第 i
行 j
列的传送带运作方向,"^","v","<",">"
这四种符号分别表示 上、下、左、右 四个方向。信物会随传送带的方向移动。勇者每一次施法操作,可临时变更一处传送带的方向,在物品经过后传送带恢复原方向。
通关信物初始位于坐标 start
处,勇者需要将其移动到坐标 end
处,请返回勇者施法操作的最少次数。
Example
输入:matrix = [">>v","v^<","<><"], start = [0,1], end = [2,0]
输出:1
代码 [01BFS]
class Solution {
private:
int DIR[4][2]{{-1, 0}, {1, 0}, {0, -1}, {0, 1},};
char SIG[4]{'^', 'v', '<', '>'};
int dist[100][100];
bool visited[100][100];
public:
int conveyorBelt(vector<string> &matrix, vector<int> &start, vector<int> &end) {
int n = matrix.size(), m = matrix[0].size();
memset(dist, 0x3f, sizeof dist);
memset(visited, 0, sizeof visited);
deque<pair<int, int>> deq;
deq.emplace_back(start[0], start[1]);
dist[start[0]][start[1]] = 0;
while (!deq.empty()) {
auto[x, y]=deq.front();
deq.pop_front();
if (visited[x][y]) continue;
if (x == end[0] && y == end[1]) break;
visited[x][y] = true;
for (int i = 0; i < 4; ++i) {
int nx = x + DIR[i][0], ny = y + DIR[i][1];
if (nx < 0 || ny < 0 || nx == n || ny == m) continue;
int ndist = dist[x][y] + (SIG[i] != matrix[x][y]);
if (ndist >= dist[nx][ny]) continue;
dist[nx][ny] = ndist;
SIG[i] != matrix[x][y] ? deq.emplace_back(nx, ny) : deq.emplace_front(nx, ny);
}
}
return dist[end[0]][end[1]];
}
};
2. 最长特殊序列 II
Given an array of strings strs
, return the length of the longest uncommon subsequence between them. If the longest uncommon subsequence does not exist, return -1
.
An uncommon subsequence between an array of strings is a string that is a subsequence of one string but not the others.
Example
Input: strs = ["aba","cdc","eae"]
Output: 3
代码
class Solution:
def findLUSlength(self, strs: List[str]) -> int:
def is_sub_str(s1: str, s2: str) -> bool:
if len(s2) < len(s1): return False
i = j = 0
while i < len(s1) and j < len(s2):
if s1[i] == s2[j]: i += 1
j += 1
return i == len(s1)
ans = -1
for i, s in enumerate(strs):
if len(s) > ans and all(not is_sub_str(s, s_) for j, s_ in enumerate(strs) if j != i):
ans = len(s)
return ans
3. T 秒后青蛙的位置
给你一棵由 n 个顶点组成的无向树,顶点编号从 1 到 n
。青蛙从 顶点 1 开始起跳。规则如下:
-
在一秒内,青蛙从它所在的当前顶点跳到另一个 未访问 过的顶点(如果它们直接相连)。
-
青蛙无法跳回已经访问过的顶点。
-
如果青蛙可以跳到多个不同顶点,那么它跳到其中任意一个顶点上的机率都相同。
-
如果青蛙不能跳到任何未访问过的顶点上,那么它每次跳跃都会停留在原地。
无向树的边用数组 edges
描述,其中 edges[i] = [fromi, toi]
意味着存在一条直接连通 fromi
和 toi
两个顶点的边。
返回青蛙在 t
秒后位于目标顶点 target
上的概率。
Example
输入:n = 7, edges = [[1,2],[1,3],[1,7],[2,4],[2,6],[3,5]], t = 2, target = 4
输出:0.16666666666666666
代码 [BFS]
class Solution {
private:
bool visited[101], isEnd[101];
int time[101];
double prob[101];
public:
double frogPosition(int n, vector<vector<int>> &edges, int t, int target) {
memset(visited, 0, sizeof visited);
memset(isEnd, 0, sizeof isEnd);
memset(time, 0, sizeof time);
memset(prob, 0, sizeof prob);
prob[1] = 1;
unordered_map<int, unordered_set<int>> mp;
for (auto &edge:edges) {
mp[edge[0]].insert(edge[1]);
mp[edge[1]].insert(edge[0]);
}
queue<int> q;
q.push(1);
while (!q.empty()) {
int node = q.front();
q.pop();
visited[node] = true;
int children = 0;
for (auto next:mp[node]) {
if (!visited[next]) children++;
}
if (children == 0) {
isEnd[node] = true;
continue;
}
double np = prob[node] / children;
for (auto next:mp[node]) {
if (visited[next]) continue;
prob[next] = np;
time[next] = time[node] + 1;
q.push(next);
}
}
if (t < time[target]) return 0;
if (t == time[target] || isEnd[target]) return prob[target];
return 0;
}
};
代码 2 [BFS-剪枝]
class Solution {
private:
bool visited[101];
int time[101];
double prob[101];
public:
double frogPosition(int n, const vector<vector<int>> &edges, int t, int target) {
memset(visited, 0, sizeof visited);
memset(time, 0, sizeof time);
memset(prob, 0, sizeof prob);
prob[1] = 1;
vector<vector<int>> mp(n + 1);
for (auto &edge:edges) {
mp[edge[0]].push_back(edge[1]);
mp[edge[1]].push_back(edge[0]);
}
queue<int> q;
q.push(1);
while (!q.empty()) {
int node = q.front();
q.pop();
visited[node] = true;
int children = 0;
for (auto next:mp[node]) {
if (!visited[next]) children++;
}
if (children == 0) {
if (target == node) return t >= time[node] ? prob[node] : 0;
continue;
} else {
if (target == node) return t == time[node] ? prob[node] : 0;
}
double np = prob[node] / children;
for (auto next:mp[node]) {
if (visited[next]) continue;
prob[next] = np;
time[next] = time[node] + 1;
q.push(next);
}
}
return t == time[target] ? prob[target] : 0;
}
};