力扣刷题:1436. 旅行终点站问题
在这篇博客中,我们将讨论力扣第1436题——旅行终点站。这道题要求我们从给定的路径列表中找出没有出现在任何其他城市的出发列表中的城市,也就是说,它是终点站。这道题在算法上并不复杂,暴力解法即可解决,我们也会讨论其具体实现。
题目描述
给你一份旅游线路图,该线路图中的旅行线路用数组 paths
表示,其中 paths[i] = [cityAi, cityBi]
表示从 cityAi
直接前往 cityBi
。请你找出这次旅行的终点站,即没有任何线路通往其他城市的终点城市。
题目数据保证线路图形成一条不存在循环的线路,因此恰好存在一个旅行终点站。
示例
-
示例 1:
输入:paths = [["London", "New York"], ["New York", "Lima"], ["Lima", "Sao Paulo"]] 输出:"Sao Paulo"
-
示例 2:
输入:paths = [["B", "C"], ["D", "B"], ["C", "A"]] 输出:"A"
-
示例 3:
输入:paths = [["A", "Z"]] 输出:"Z"
解法思路
1. 暴力解法
这道题的核心思路是:终点站是不会出现在任何其他路径的起点的城市。因此,我们只需要检查每一个目的地,看它是否存在于其他路径的起点中。如果某个目的地不在起点列表中,那它就是终点站。
题目保证路径数量 n <= 100
,因此使用暴力解法检查所有目的地是否在起点中是可行的。时间复杂度为 (O(n^2)),可以接受。
各种语言实现
我们分别用 C++、Python、Go 和 Java 进行实现。
C++ 实现
class Solution {
public:
string destCity(vector<vector<string>>& paths) {
string res = "";
for (int i = 0; i < paths.size(); i++) {
bool flag = true;
for (int j = 0; j < paths.size(); j++) {
if (i == j) {
continue;
}
if (paths[i][1] == paths[j][0]) {
flag = false;
break;
}
}
if (flag) {
res = paths[i][1];
return res;
}
}
return res;
}
};
C++ 代码说明
- 外层循环遍历每一个目的地
paths[i][1]
。 - 内层循环遍历起点
paths[j][0]
,检查目的地是否为某个路径的起点。 - 如果某个目的地没有出现在起点列表中,则它是终点站,返回该城市。
Python 实现
class Solution:
def destCity(self, paths: List[List[str]]) -> str:
for i in paths:
flag = True
for j in paths:
if i == j:
continue
if i[1] == j[0]:
flag = False
if flag:
return i[1]
Python 代码说明
- 使用两层循环,遍历每个目的地
i[1]
和起点j[0]
。 - 如果目的地
i[1]
没有出现在任何起点中,则返回它。
Go 实现
接下来我们用 Go 实现相同的逻辑。
package main
func destCity(paths [][]string) string {
for i := 0; i < len(paths); i++ {
flag := true
for j := 0; j < len(paths); j++ {
if i == j {
continue
}
if paths[i][1] == paths[j][0] {
flag = false
break
}
}
if flag {
return paths[i][1]
}
}
return ""
}
Go 代码说明
- Go 的代码逻辑与 C++ 和 Python 相似。使用双层循环,外层遍历目的地,内层遍历起点。
- 若某个目的地不作为起点出现,则返回它作为终点站。
Java 实现
最后,用 Java 实现相同的逻辑:
class Solution {
public String destCity(List<List<String>> paths) {
for (List<String> path : paths) {
boolean flag = true;
for (List<String> path2 : paths) {
if (path.equals(path2)) {
continue;
}
if (path.get(1).equals(path2.get(0))) {
flag = false;
break;
}
}
if (flag) {
return path.get(1);
}
}
return "";
}
}
Java 代码说明
- 外层循环遍历目的地
path.get(1)
,内层循环遍历起点path2.get(0)
。 - 如果
path.get(1)
没有出现在起点中,返回它作为终点站。
总结
在这篇博客中,我们探讨了力扣第 1436 题 旅行终点站 的解法。通过暴力解法,我们能够简单地解决这个问题。由于题目的数据规模较小,时间复杂度 (O(n^2)) 是可以接受的。我们为 C++、Python、Go 和 Java 提供了相应的实现。
这种题目适合初学者通过暴力解法练习,同时可以进一步优化,例如使用集合存储起点城市来降低查找的时间复杂度到 (O(n))。
你可以尝试的优化
如果你想进一步优化代码,可以尝试使用集合来存储所有的起点城市,然后检查每一个目的地是否在集合中。这样可以减少内层循环,优化时间复杂度。
这类题目有助于锻炼我们对数据结构和算法的基本掌握,特别是对于暴力解法和简单优化的理解。希望这个题解能帮助你更好地理解和解决类似问题。