Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 7235d3e

Browse files
feat: add solutions to lc problem: No.1548 (#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‎

Lines changed: 248 additions & 1 deletion
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)

AltStyle によって変換されたページ (->オリジナル) /