Skip to content

Commit 7235d3e

Browse files
authored
feat: add solutions to lc problem: No.1548 (doocs#1632)
1 parent 66da16b commit 7235d3e

File tree

7 files changed

+714
-2
lines changed

7 files changed

+714
-2
lines changed

solution/1500-1599/1548.The Most Similar Path in a Graph/README.md

+248-1
Original file line numberDiff line numberDiff line change
@@ -80,22 +80,269 @@
8080

8181
<!-- 这里可写通用的实现逻辑 -->
8282

83+
**方法一:动态规划**
84+
85+
我们先根据给定的道路构建一个邻接表 $g$,其中 $g[i]$ 表示与城市 $i$ 直接相连的城市列表。
86+
87+
然后我们定义 $f[i][j]$ 表示 $targetPath$ 的第 $i$ 个城市与 $names$ 的第 $j$ 个城市匹配时,前 $i$ 个城市的最小编辑距离。
88+
89+
那么我们可以得到状态转移方程:
90+
91+
$$
92+
f[i][j] = \min_{k \in g[j]} f[i - 1][k] + (targetPath[i] \neq names[j])
93+
$$
94+
95+
在状态转移的过程中,我们记录下每个状态的前驱城市,最后根据前驱城市数组 $pre$ 从后往前还原出最优路径。
96+
97+
时间复杂度 $O(m \times n^2)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别是 $targetPath$ 和 $names$ 的长度。
98+
8399
<!-- tabs:start -->
84100

85101
### **Python3**
86102

87103
<!-- 这里可写当前语言的特殊实现逻辑 -->
88104

89105
```python
90-
106+
class Solution:
107+
def mostSimilar(
108+
self, n: int, roads: List[List[int]], names: List[str], targetPath: List[str]
109+
) -> List[int]:
110+
g = [[] for _ in range(n)]
111+
for a, b in roads:
112+
g[a].append(b)
113+
g[b].append(a)
114+
m = len(targetPath)
115+
f = [[inf] * n for _ in range(m)]
116+
pre = [[-1] * n for _ in range(m)]
117+
for j, s in enumerate(names):
118+
f[0][j] = targetPath[0] != s
119+
for i in range(1, m):
120+
for j in range(n):
121+
for k in g[j]:
122+
if (t := f[i - 1][k] + (targetPath[i] != names[j])) < f[i][j]:
123+
f[i][j] = t
124+
pre[i][j] = k
125+
k = 0
126+
mi = inf
127+
for j in range(n):
128+
if f[-1][j] < mi:
129+
mi = f[-1][j]
130+
k = j
131+
ans = [0] * m
132+
for i in range(m - 1, -1, -1):
133+
ans[i] = k
134+
k = pre[i][k]
135+
return ans
91136
```
92137

93138
### **Java**
94139

95140
<!-- 这里可写当前语言的特殊实现逻辑 -->
96141

97142
```java
143+
class Solution {
144+
public List<Integer> mostSimilar(int n, int[][] roads, String[] names, String[] targetPath) {
145+
List<Integer>[] g = new List[n];
146+
Arrays.setAll(g, i -> new ArrayList<>());
147+
for (int[] r : roads) {
148+
int a = r[0], b = r[1];
149+
g[a].add(b);
150+
g[b].add(a);
151+
}
152+
int m = targetPath.length;
153+
final int inf = 1 << 30;
154+
int[][] f = new int[m][n];
155+
int[][] pre = new int[m][n];
156+
for (int i = 0; i < m; i++) {
157+
Arrays.fill(f[i], inf);
158+
Arrays.fill(pre[i], -1);
159+
}
160+
for (int j = 0; j < n; ++j) {
161+
f[0][j] = targetPath[0].equals(names[j]) ? 0 : 1;
162+
}
163+
for (int i = 1; i < m; ++i) {
164+
for (int j = 0; j < n; ++j) {
165+
for (int k : g[j]) {
166+
int t = f[i - 1][k] + (targetPath[i].equals(names[j]) ? 0 : 1);
167+
if (t < f[i][j]) {
168+
f[i][j] = t;
169+
pre[i][j] = k;
170+
}
171+
}
172+
}
173+
}
174+
int mi = inf, k = 0;
175+
for (int j = 0; j < n; ++j) {
176+
if (f[m - 1][j] < mi) {
177+
mi = f[m - 1][j];
178+
k = j;
179+
}
180+
}
181+
List<Integer> ans = new ArrayList<>();
182+
for (int i = m - 1; i >= 0; --i) {
183+
ans.add(k);
184+
k = pre[i][k];
185+
}
186+
Collections.reverse(ans);
187+
return ans;
188+
}
189+
}
190+
```
191+
192+
### **C++**
193+
194+
```cpp
195+
class Solution {
196+
public:
197+
vector<int> mostSimilar(int n, vector<vector<int>>& roads, vector<string>& names, vector<string>& targetPath) {
198+
vector<int> g[n];
199+
for (auto& r : roads) {
200+
int a = r[0], b = r[1];
201+
g[a].push_back(b);
202+
g[b].push_back(a);
203+
}
204+
int m = targetPath.size();
205+
int f[m][n];
206+
int pre[m][n];
207+
memset(f, 0x3f, sizeof(f));
208+
memset(pre, -1, sizeof(pre));
209+
for (int j = 0; j < n; ++j) {
210+
f[0][j] = targetPath[0] != names[j];
211+
}
212+
for (int i = 1; i < m; ++i) {
213+
for (int j = 0; j < n; ++j) {
214+
for (int k : g[j]) {
215+
int t = f[i - 1][k] + (targetPath[i] != names[j]);
216+
if (t < f[i][j]) {
217+
f[i][j] = t;
218+
pre[i][j] = k;
219+
}
220+
}
221+
}
222+
}
223+
int k = 0;
224+
int mi = 1 << 30;
225+
for (int j = 0; j < n; ++j) {
226+
if (f[m - 1][j] < mi) {
227+
mi = f[m - 1][j];
228+
k = j;
229+
}
230+
}
231+
vector<int> ans(m);
232+
for (int i = m - 1; ~i; --i) {
233+
ans[i] = k;
234+
k = pre[i][k];
235+
}
236+
return ans;
237+
}
238+
};
239+
```
240+
241+
### **Go**
242+
243+
```go
244+
func mostSimilar(n int, roads [][]int, names []string, targetPath []string) []int {
245+
g := make([][]int, n)
246+
for _, r := range roads {
247+
a, b := r[0], r[1]
248+
g[a] = append(g[a], b)
249+
g[b] = append(g[b], a)
250+
}
251+
m := len(targetPath)
252+
const inf = 1 << 30
253+
f := make([][]int, m)
254+
pre := make([][]int, m)
255+
for i := range f {
256+
f[i] = make([]int, n)
257+
pre[i] = make([]int, n)
258+
for j := range f[i] {
259+
f[i][j] = inf
260+
pre[i][j] = -1
261+
}
262+
}
263+
for j, s := range names {
264+
if targetPath[0] != s {
265+
f[0][j] = 1
266+
} else {
267+
f[0][j] = 0
268+
}
269+
}
270+
for i := 1; i < m; i++ {
271+
for j := 0; j < n; j++ {
272+
for _, k := range g[j] {
273+
t := f[i-1][k]
274+
if targetPath[i] != names[j] {
275+
t++
276+
}
277+
if t < f[i][j] {
278+
f[i][j] = t
279+
pre[i][j] = k
280+
}
281+
}
282+
}
283+
}
284+
mi, k := inf, 0
285+
for j := 0; j < n; j++ {
286+
if f[m-1][j] < mi {
287+
mi = f[m-1][j]
288+
k = j
289+
}
290+
}
291+
ans := make([]int, m)
292+
for i := m - 1; i >= 0; i-- {
293+
ans[i] = k
294+
k = pre[i][k]
295+
}
296+
return ans
297+
}
298+
```
98299

300+
### **TypeScript**
301+
302+
```ts
303+
function mostSimilar(
304+
n: number,
305+
roads: number[][],
306+
names: string[],
307+
targetPath: string[],
308+
): number[] {
309+
const g: number[][] = Array.from({ length: n }, () => []);
310+
for (const [a, b] of roads) {
311+
g[a].push(b);
312+
g[b].push(a);
313+
}
314+
const m = targetPath.length;
315+
const f = Array.from({ length: m }, () => Array.from({ length: n }, () => Infinity));
316+
const pre: number[][] = Array.from({ length: m }, () => Array.from({ length: n }, () => -1));
317+
for (let j = 0; j < n; ++j) {
318+
f[0][j] = names[j] === targetPath[0] ? 0 : 1;
319+
}
320+
for (let i = 1; i < m; ++i) {
321+
for (let j = 0; j < n; ++j) {
322+
for (const k of g[j]) {
323+
const t = f[i - 1][k] + (names[j] === targetPath[i] ? 0 : 1);
324+
if (t < f[i][j]) {
325+
f[i][j] = t;
326+
pre[i][j] = k;
327+
}
328+
}
329+
}
330+
}
331+
let k = 0;
332+
let mi = Infinity;
333+
for (let j = 0; j < n; ++j) {
334+
if (f[m - 1][j] < mi) {
335+
mi = f[m - 1][j];
336+
k = j;
337+
}
338+
}
339+
const ans: number[] = Array(m).fill(0);
340+
for (let i = m - 1; ~i; --i) {
341+
ans[i] = k;
342+
k = pre[i][k];
343+
}
344+
return ans;
345+
}
99346
```
100347

101348
### **...**

0 commit comments

Comments
 (0)