图
图基础
图的表示
java
// 邻接矩阵
int[][] graph = new int[n][n];
graph[i][j] = 1; // 表示i到j有边
// 邻接表
List<List<Integer>> graph = new ArrayList<>();
for (int i = 0; i < n; i++) {
graph.add(new ArrayList<>());
}
graph.get(i).add(j); // 表示i到j有边图的遍历
深度优先搜索(DFS)
java
public void dfs(List<List<Integer>> graph, int node, boolean[] visited) {
visited[node] = true;
System.out.println(node);
for (int neighbor : graph.get(node)) {
if (!visited[neighbor]) {
dfs(graph, neighbor, visited);
}
}
}广度优先搜索(BFS)
java
public void bfs(List<List<Integer>> graph, int start) {
boolean[] visited = new boolean[graph.size()];
Queue<Integer> queue = new LinkedList<>();
queue.offer(start);
visited[start] = true;
while (!queue.isEmpty()) {
int node = queue.poll();
System.out.println(node);
for (int neighbor : graph.get(node)) {
if (!visited[neighbor]) {
queue.offer(neighbor);
visited[neighbor] = true;
}
}
}
}图的经典题目
岛屿数量(LeetCode 200)
答案:
java
public int numIslands(char[][] grid) {
int count = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == '1') {
dfs(grid, i, j);
count++;
}
}
}
return count;
}
private void dfs(char[][] grid, int i, int j) {
if (i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == '0') {
return;
}
grid[i][j] = '0';
dfs(grid, i + 1, j);
dfs(grid, i - 1, j);
dfs(grid, i, j + 1);
dfs(grid, i, j - 1);
}课程表(LeetCode 207)
答案:
java
public boolean canFinish(int numCourses, int[][] prerequisites) {
List<List<Integer>> graph = new ArrayList<>();
int[] indegree = new int[numCourses];
for (int i = 0; i < numCourses; i++) {
graph.add(new ArrayList<>());
}
for (int[] pre : prerequisites) {
graph.get(pre[1]).add(pre[0]);
indegree[pre[0]]++;
}
Queue<Integer> queue = new LinkedList<>();
for (int i = 0; i < numCourses; i++) {
if (indegree[i] == 0) {
queue.offer(i);
}
}
int count = 0;
while (!queue.isEmpty()) {
int course = queue.poll();
count++;
for (int next : graph.get(course)) {
indegree[next]--;
if (indegree[next] == 0) {
queue.offer(next);
}
}
}
return count == numCourses;
}克隆图(LeetCode 133)
答案:
java
class Node {
public int val;
public List<Node> neighbors;
}
public Node cloneGraph(Node node) {
if (node == null) return null;
Map<Node, Node> map = new HashMap<>();
return dfs(node, map);
}
private Node dfs(Node node, Map<Node, Node> map) {
if (map.containsKey(node)) {
return map.get(node);
}
Node clone = new Node(node.val, new ArrayList<>());
map.put(node, clone);
for (Node neighbor : node.neighbors) {
clone.neighbors.add(dfs(neighbor, map));
}
return clone;
}最短路径
网络延迟时间(LeetCode 743)
答案:
java
public int networkDelayTime(int[][] times, int n, int k) {
Map<Integer, List<int[]>> graph = new HashMap<>();
for (int[] time : times) {
graph.putIfAbsent(time[0], new ArrayList<>());
graph.get(time[0]).add(new int[]{time[1], time[2]});
}
int[] dist = new int[n + 1];
Arrays.fill(dist, Integer.MAX_VALUE);
dist[k] = 0;
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[1] - b[1]);
pq.offer(new int[]{k, 0});
while (!pq.isEmpty()) {
int[] curr = pq.poll();
int node = curr[0];
int time = curr[1];
if (time > dist[node]) continue;
if (graph.containsKey(node)) {
for (int[] edge : graph.get(node)) {
int next = edge[0];
int newTime = time + edge[1];
if (newTime < dist[next]) {
dist[next] = newTime;
pq.offer(new int[]{next, newTime});
}
}
}
}
int maxTime = 0;
for (int i = 1; i <= n; i++) {
if (dist[i] == Integer.MAX_VALUE) return -1;
maxTime = Math.max(maxTime, dist[i]);
}
return maxTime;
}练习题
- 腐烂的橘子(LeetCode 994)
- 被围绕的区域(LeetCode 130)
- 太平洋大西洋水流问题(LeetCode 417)
- 冗余连接(LeetCode 684)
- 最小高度树(LeetCode 310)