diff --git a/src/main/java/com/dota/graph/Solution.java b/src/main/java/com/dota/graph/Solution.java index 0ebce4e..951bc15 100644 --- a/src/main/java/com/dota/graph/Solution.java +++ b/src/main/java/com/dota/graph/Solution.java @@ -4,67 +4,187 @@ import java.util.*; class Solution { - long res = 0; - int sum = 0; + long res = 0; + int sum = 0; - public long minimumFuelCost(int[][] roads, int seats) { - List[] map = new List[roads.length + 1]; - for (int i = 0; i < map.length; i++) { - map[i] = new ArrayList<>(); - } + public long minimumFuelCost(int[][] roads, int seats) { + List[] map = new List[roads.length + 1]; + for (int i = 0; i < map.length; i++) { + map[i] = new ArrayList<>(); + } - for (int[] road : roads) { - map[road[0]].add(road[1]); - map[road[1]].add(road[0]); - } + for (int[] road : roads) { + map[road[0]].add(road[1]); + map[road[1]].add(road[0]); + } - dfs(0, -1, seats, map); - return res; - } + dfs(0, -1, seats, map); + return res; + } - int dfs(int start, int from, int seats, List[] map) { - int cur = 1; - for (Integer i : map[start]) { - if (i != from) { - int childSum = dfs(i, start, seats, map); - cur += childSum; - res += (childSum + seats - 1) / seats; - } - } + int dfs(int start, int from, int seats, List[] map) { + int cur = 1; + for (Integer i : map[start]) { + if (i != from) { + int childSum = dfs(i, start, seats, map); + cur += childSum; + res += (childSum + seats - 1) / seats; + } + } - return cur; - } + return cur; + } - // 1466. 重新规划路线 - public int minReorder(int n, int[][] connections) { - List[] list = new List[n]; - List[] otherList = new List[n]; - for (int i = 0; i < list.length; i++) { - list[i] = new ArrayList<>(); - otherList[i] = new ArrayList<>(); - } + // 1466. 重新规划路线 + public int minReorder(int n, int[][] connections) { + List[] list = new List[n]; + List[] otherList = new List[n]; + for (int i = 0; i < list.length; i++) { + list[i] = new ArrayList<>(); + otherList[i] = new ArrayList<>(); + } - for (int[] ints : connections) { - list[ints[0]].add(ints[1]); - otherList[ints[1]].add(ints[0]); - } + for (int[] ints : connections) { + list[ints[0]].add(ints[1]); + otherList[ints[1]].add(ints[0]); + } - dfs(0, -1, list, otherList); - return sum; - } + dfs(0, -1, list, otherList); + return sum; + } - private void dfs(int now, int parent, List[] list, List[] otherList) { - for (int i = 0; i < list[now].size(); i++) { - if (list[now].get(i) != parent) { - sum++; - dfs(list[now].get(i), now, list, otherList); - } - } + private void dfs(int now, int parent, List[] list, List[] otherList) { + for (int i = 0; i < list[now].size(); i++) { + if (list[now].get(i) != parent) { + sum++; + dfs(list[now].get(i), now, list, otherList); + } + } - for (int i = 0; i < otherList[now].size(); i++) { - if (otherList[now].get(i) != parent) { - dfs(otherList[now].get(i), now, list, otherList); - } - } - } + for (int i = 0; i < otherList[now].size(); i++) { + if (otherList[now].get(i) != parent) { + dfs(otherList[now].get(i), now, list, otherList); + } + } + } + + int min = Integer.MAX_VALUE; + + int N = 10001; + int[] union = new int[N]; + + int find(int x) { + while (union[x] != x) { + union[x] = union[union[x]]; + x = union[x]; + } + return x; + } + + // 使用并查集 + public int minimumEffortPath(int[][] heights) { + for (int i = 0; i < N; i++) { + union[i] = i; + } + + int n = heights.length; + int m = heights[0].length; + List list = new ArrayList<>(1000001); + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + int idx = index(i, j, n, m); + int i1 = index(i, j + 1, n, m); + int i2 = index(i + 1, j, n, m); + if (i1 != -1) { + int hei = Math.abs(heights[i][j]-heights[i][j+1]); + list.add(new int[]{idx, i1, hei}); + } + if (i2 != -1) { + int hei = Math.abs(heights[i][j]-heights[i+1][j]); + list.add(new int[]{idx, i2, hei}); + } + } + } + + for (int[] ints : list) { + union[find(ints[0])] = find(ints[1]); + if (find(0)==find(n*m-1)) { + return ints[2]; + } + } + return 0; + } + + int index(int i, int j, int n, int m) { + if (i < 0 || j < 0 || i >= n || j >= m) { + return -1; + } + + return (i * m) + j; + } } + +class Solution1 { + + private int[] parent; + private Edge[] edges = new Edge[1000001]; + + public int minimumEffortPath(int[][] heights) { + int m = heights.length, n = heights[0].length; + if (m == 1 && n == 1) return 0; + + parent = new int[m * n]; + for (int i = 0; i < m * n; i++) parent[i] = i; + + int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE; + + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (i < m-1) { + int diff = Math.abs(heights[i][j] - heights[i+1][j]); + edges[diff] = new Edge(i * n + j, (i+1) * n + j, edges[diff]); + if(diff > max) max = diff; + if(diff < min) min = diff; + } + + if (j < n-1) { + int diff = Math.abs(heights[i][j] - heights[i][j+1]); + edges[diff] = new Edge(i * n + j, i * n + (j+1), edges[diff]); + if(diff > max) max = diff; + if(diff < min) min = diff; + } + } + } + + for(int i = min; i <= max; ++i){ + for (Edge e = edges[i]; e != null; e = e.next) { + int xParent = find(e.x, parent), yParent = find(e.y, parent); + parent[xParent] = yParent; + + if (find(0, parent) == find(m * n -1, parent)) return i; + } + } + + return 0; + } + + private int find(int x, int[] parent) { + while (parent[x] != x) { + parent[x] = parent[parent[x]]; + x = parent[x]; + } + return x; + } + + class Edge { + int x, y; + Edge next; + + Edge(int x, int y, Edge next) { + this.x = x; + this.y = y; + this.next = next; + } + } +} +