From 25ca0edcdaae2536c89d4ee41223c4a19611653b Mon Sep 17 00:00:00 2001 From: algorithmzuo Date: Thu, 13 Jul 2023 14:27:53 +0800 Subject: [PATCH] modify code --- .../Code01_GreedyPickThings.java | 62 +++++ .../Code02_RobotPassThroughBuilding.java | 81 ++++++ .../Code03_PutMarblesInBags.java | 35 +++ ...MaximumEmployeesToBeInvitedToAMeeting.java | 104 ++++++++ ...05_FindCriticalAndPseudoCriticalEdges.java | 244 ++++++++++++++++++ ...¥å…»çš„大厂算法é¢è¯•é¢˜(正在直播) | 60 +++++ 6 files changed, 586 insertions(+) create mode 100644 算法周更ç­/class_2023_07_2_week/Code01_GreedyPickThings.java create mode 100644 算法周更ç­/class_2023_07_2_week/Code02_RobotPassThroughBuilding.java create mode 100644 算法周更ç­/class_2023_07_2_week/Code03_PutMarblesInBags.java create mode 100644 算法周更ç­/class_2023_07_2_week/Code04_MaximumEmployeesToBeInvitedToAMeeting.java create mode 100644 算法周更ç­/class_2023_07_2_week/Code05_FindCriticalAndPseudoCriticalEdges.java diff --git a/算法周更ç­/class_2023_07_2_week/Code01_GreedyPickThings.java b/算法周更ç­/class_2023_07_2_week/Code01_GreedyPickThings.java new file mode 100644 index 0000000..81254fb --- /dev/null +++ b/算法周更ç­/class_2023_07_2_week/Code01_GreedyPickThings.java @@ -0,0 +1,62 @@ +package class_2023_07_2_week; + +// 阿里巴巴走进了装满å®è—çš„è—å®æ´žã€‚è—å®æ´žé‡Œé¢æœ‰Nå †é‡‘å¸ +// 第i堆金å¸çš„总é‡é‡å’Œæ€»ä»·å€¼åˆ†åˆ«æ˜¯m[i]ã€v[i] +// 阿里巴巴有一个承é‡é‡ä¸ºT的背包,但并ä¸ä¸€å®šæœ‰åŠžæ³•å°†å…¨éƒ¨çš„金å¸éƒ½è£…进去 +// 他想装走尽å¯èƒ½å¤šä»·å€¼çš„é‡‘å¸ +// 所有金å¸éƒ½å¯ä»¥éšæ„分割,分割完的金å¸é‡é‡ä»·å€¼æ¯”(也就是å•ä½ä»·æ ¼ï¼‰ä¸å˜ +// 请问阿里巴巴最多å¯ä»¥æ‹¿èµ°å¤šå°‘价值的金å¸ï¼Ÿ +// 测试链接 : https://www.luogu.com.cn/problem/P2240 +// 请åŒå­¦ä»¬åŠ¡å¿…å‚考如下代ç ä¸­å…³äºŽè¾“å…¥ã€è¾“å‡ºçš„å¤„ç† +// 这是输入输出处ç†æ•ˆçŽ‡å¾ˆé«˜çš„写法 +// æ交以下的code,æ交时请把类å改æˆ"Main",å¯ä»¥ç›´æŽ¥é€šè¿‡ + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.StreamTokenizer; +import java.util.Arrays; + +public class Code01_GreedyPickThings { + + public static int MAXN = 101; + + // mv[i][0] + // mv[i][1] + public static int[][] mv = new int[MAXN][2]; + + public static int n, t; + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StreamTokenizer in = new StreamTokenizer(br); + PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out)); + while (in.nextToken() != StreamTokenizer.TT_EOF) { + n = (int) in.nval; + in.nextToken(); + t = (int) in.nval; + for (int i = 0; i < n; i++) { + in.nextToken(); + mv[i][0] = (int) in.nval; + in.nextToken(); + mv[i][1] = (int) in.nval; + } + Arrays.sort(mv, 0, n, (a, b) -> (b[1] * a[0]) - (a[1] * b[0])); + double ans = 0; + int i = 0; + int used = 0; + for (; i < n && used + mv[i][0] <= t; i++) { + used += mv[i][0]; + ans += mv[i][1]; + } + if (i < n) { + ans += (double) mv[i][1] * (t - used) / (double) mv[i][0]; + } + out.println(String.format("%.2f", ans)); + out.flush(); + } + } + +} diff --git a/算法周更ç­/class_2023_07_2_week/Code02_RobotPassThroughBuilding.java b/算法周更ç­/class_2023_07_2_week/Code02_RobotPassThroughBuilding.java new file mode 100644 index 0000000..25d9587 --- /dev/null +++ b/算法周更ç­/class_2023_07_2_week/Code02_RobotPassThroughBuilding.java @@ -0,0 +1,81 @@ +package class_2023_07_2_week; + +// æ¥è‡ªå­—节 +// 机器人正在玩一个å¤è€çš„基于DOSçš„æ¸¸æˆ +// 游æˆä¸­æœ‰N+1座建筑,从0到Nç¼–å·ï¼Œä»Žå·¦åˆ°å³æŽ’列 +// ç¼–å·ä¸º0的建筑高度为0个å•ä½ï¼Œç¼–å·ä¸ºi的建筑的高度为H(i)个å•ä½ +// èµ·åˆï¼Œ 机器人在编å·ä¸º0的建筑处 +// æ¯ä¸€æ­¥ï¼Œå®ƒè·³åˆ°ä¸‹ä¸€ä¸ªï¼ˆå³è¾¹ï¼‰å»ºç­‘。å‡è®¾æœºå™¨äººåœ¨ç¬¬k个建筑,且它现在的能é‡å€¼æ˜¯E +// 下一步它将跳到第个k+1建筑 +// 它将会得到或者失去正比于与H(k+1)与Eä¹‹å·®çš„èƒ½é‡ +// 如果 H(k+1) > E 那么机器人就失去H(k+1)-E的能é‡å€¼ï¼Œå¦åˆ™å®ƒå°†å¾—到E-H(k+1)的能é‡å€¼ +// 游æˆç›®æ ‡æ˜¯åˆ°è¾¾ç¬¬ä¸ªN建筑,在这个过程中,能é‡å€¼ä¸èƒ½ä¸ºè´Ÿæ•°ä¸ªå•ä½ +// 现在的问题是机器人以多少能é‡å€¼å¼€å§‹æ¸¸æˆï¼Œæ‰å¯ä»¥ä¿è¯æˆåŠŸå®Œæˆæ¸¸æˆ +// 测试链接 : https://www.nowcoder.com/questionTerminal/7037a3d57bbd4336856b8e16a9cafd71 +// 请åŒå­¦ä»¬åŠ¡å¿…å‚考如下代ç ä¸­å…³äºŽè¾“å…¥ã€è¾“å‡ºçš„å¤„ç† +// 这是输入输出处ç†æ•ˆçŽ‡å¾ˆé«˜çš„写法 +// æ交以下的code,æ交时请把类å改æˆ"Main",å¯ä»¥ç›´æŽ¥é€šè¿‡ + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.StreamTokenizer; + +public class Code02_RobotPassThroughBuilding { + + public static int MAXN = 100001; + + public static int[] arr = new int[MAXN]; + + public static int n; + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StreamTokenizer in = new StreamTokenizer(br); + PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out)); + while (in.nextToken() != StreamTokenizer.TT_EOF) { + n = (int) in.nval; + int l = 0; + int r = 0; + int max = 0; + for (int i = 0; i < n; i++) { + in.nextToken(); + arr[i] = (int) in.nval; + r = Math.max(r, arr[i]); + max = r; + } + int m, ans = -1; + while (l <= r) { + m = (l + r) / 2; + if (ok(m, max)) { + ans = m; + r = m - 1; + } else { + l = m + 1; + } + } + out.println(ans); + out.flush(); + } + } + + public static boolean ok(int sum, int max) { + // 注æ„ï¼ + // 如果你给的能é‡å€¼å¾ˆå¤§ï¼Œé‚£ä¹ˆè¿™ä¸ªèƒ½é‡å¢žé•¿çš„å°†éžå¸¸æ怖 + // 甚至有å¯èƒ½è¶…出long的范围,这就是为什么改æˆlong也ä¸å¯¹ + // 所以è¦åŠ sum <= max这一å¥åˆ¤æ–­ï¼Œä¸€æ—¦èƒ½é‡ç´¯åŠ å’Œè¶…过高度的最大值 + // åŽé¢è‚¯å®šé€šå…³äº†ï¼Œå¯ä»¥æå‰è¿”回 + // 总之是很阴 + for (int i = 0; i < n && sum >= 0 && sum <= max; i++) { + if (sum <= arr[i]) { + sum -= arr[i] - sum; + } else { + sum += sum - arr[i]; + } + } + return sum >= 0; + } + +} diff --git a/算法周更ç­/class_2023_07_2_week/Code03_PutMarblesInBags.java b/算法周更ç­/class_2023_07_2_week/Code03_PutMarblesInBags.java new file mode 100644 index 0000000..62e7539 --- /dev/null +++ b/算法周更ç­/class_2023_07_2_week/Code03_PutMarblesInBags.java @@ -0,0 +1,35 @@ +package class_2023_07_2_week; + +import java.util.Arrays; + +// 你有 k 个背包。给你一个下标从 0 开始的整数数组 weights +// 其中 weights[i] 是第 i 个ç å­çš„é‡é‡ã€‚åŒæ—¶ç»™ä½ æ•´æ•° k +// 请你按照如下规则将所有的ç å­æ”¾è¿› k 个背包。 +// 没有背包是空的。 +// 如果第 i 个ç å­å’Œç¬¬ j 个ç å­åœ¨åŒä¸€ä¸ªèƒŒåŒ…里 +// 那么下标在 i 到 j 之间的所有ç å­éƒ½å¿…须在这åŒä¸€ä¸ªèƒŒåŒ…中 +// 如果一个背包有下标从 i 到 j 的所有ç å­ï¼Œé‚£ä¹ˆè¿™ä¸ªèƒŒåŒ…的价格是 weights[i] + weights[j] 。 +// 一个ç å­åˆ†é…方案的 分数 是所有 k 个背包的价格之和。 +// 请你返回所有分é…方案中,最大分数 与 最å°åˆ†æ•° çš„ 差值 为多少。 +// 测试链接 : https://leetcode.cn/problems/put-marbles-in-bags/ +public class Code03_PutMarblesInBags { + + public long putMarbles(int[] weights, int k) { + int n = weights.length; + long[] sums = new long[n - 1]; + for (int i = 1; i < n; i++) { + sums[i - 1] = (long) weights[i - 1] + weights[i]; + } + Arrays.sort(sums); + long ans = 0; + // å° ........ 大 + // 0 n-2 +// 1 n-3 +// 2 n-4 + for (int i = 0, j = n - 2, p = 1; p < k; i++, j--, p++) { + ans += sums[j] - sums[i]; + } + return ans; + } + +} diff --git a/算法周更ç­/class_2023_07_2_week/Code04_MaximumEmployeesToBeInvitedToAMeeting.java b/算法周更ç­/class_2023_07_2_week/Code04_MaximumEmployeesToBeInvitedToAMeeting.java new file mode 100644 index 0000000..ba3024a --- /dev/null +++ b/算法周更ç­/class_2023_07_2_week/Code04_MaximumEmployeesToBeInvitedToAMeeting.java @@ -0,0 +1,104 @@ +package class_2023_07_2_week; + +// 一个公å¸å‡†å¤‡ç»„织一场会议,邀请åå•ä¸Šæœ‰ n ä½å‘˜å·¥ +// å…¬å¸å‡†å¤‡äº†ä¸€å¼  圆形 çš„æ¡Œå­ï¼Œå¯ä»¥å下 ä»»æ„æ•°ç›® 的员工 +// 员工编å·ä¸º 0 到 n - 1 。æ¯ä½å‘˜å·¥éƒ½æœ‰ä¸€ä½ 喜欢 的员工 +// æ¯ä½å‘˜å·¥ 当且仅当 他被安排在喜欢员工的æ—边,他æ‰ä¼šå‚加会议 +// æ¯ä½å‘˜å·¥å–œæ¬¢çš„员工 ä¸ä¼š 是他自己。 +// 给你一个下标从 0 开始的整数数组 favorite +// 其中 favorite[i] 表示第 i ä½å‘˜å·¥å–œæ¬¢çš„员工。请你返回å‚加会议的 最多员工数目 +// 测试链接 : https://leetcode.cn/problems/maximum-employees-to-be-invited-to-a-meeting/ +public class Code04_MaximumEmployeesToBeInvitedToAMeeting { + + public static int maximumInvitations(int[] favorite) { + int[][] loved = beLoved(favorite); + int[] degree = degree(loved); + int n = favorite.length; + int[] queue = new int[n]; + int l = 0; + int r = 0; + for (int i = 0; i < n; i++) { + if (degree[i] == 0) { + queue[r++] = i; + } + } + boolean[] zeroVisited = new boolean[n]; + while (l < r) { + int cur = queue[l++]; + zeroVisited[cur] = true; + if (--degree[favorite[cur]] == 0) { + queue[r++] = favorite[cur]; + } + } + boolean[] cycleVisited = new boolean[n]; + int arrangeTwoCycle = 0; + int arrangeMoreCycle = 0; + for (int i = 0; i < n; i++) { + if (!zeroVisited[i] && !cycleVisited[i]) { + cycleVisited[i] = true; + if (favorite[favorite[i]] == i) { + cycleVisited[favorite[i]] = true; + arrangeTwoCycle += maxFollow(i, zeroVisited, loved) + maxFollow(favorite[i], zeroVisited, loved); + } else { + int cur = favorite[i]; + int curAns = 1; + while (cur != i) { + cycleVisited[cur] = true; + curAns++; + cur = favorite[cur]; + } + arrangeMoreCycle = Math.max(arrangeMoreCycle, curAns); + } + } + } + return Math.max(arrangeTwoCycle, arrangeMoreCycle); + } + + // 生æˆè¢«å–œæ¬¢è¡¨ + // favorite[3] = 7 + // favorite[5] = 7 + // size[ + public static int[][] beLoved(int[] favorite) { + int n = favorite.length; + int[] size = new int[n]; + // size[7] : 有多少人喜欢7 + for (int love : favorite) { + size[love]++; + } + // 7 : 3 5 + // 9 : 0 1 4 + int[][] loved = new int[n][]; + for (int i = 0; i < n; i++) { + loved[i] = new int[size[i]]; + } + for (int i = 0; i < n; i++) { + loved[favorite[i]][--size[favorite[i]]] = i; + } + return loved; + } + + // 求æ¯ä¸ªç‚¹çš„入度 + public static int[] degree(int[][] loved) { + int n = loved.length; + int[] degree = new int[n]; + for (int i = 0; i < n; i++) { + degree[i] = loved[i].length; + } + return degree; + } + + // curä¸åœ¨çŽ¯ä¸Šçš„追éšè€…链æ¡æœ€å¤§é•¿åº¦ + public static int maxFollow(int cur, boolean[] zeroed, int[][] from) { + if (from[cur].length == 0) { + return 1; + } + int ans = 0; + for (int pre : from[cur]) { + if (zeroed[pre]) { + ans = Math.max(ans, maxFollow(pre, zeroed, from)); + } + } + return ans + 1; + } + +} diff --git a/算法周更ç­/class_2023_07_2_week/Code05_FindCriticalAndPseudoCriticalEdges.java b/算法周更ç­/class_2023_07_2_week/Code05_FindCriticalAndPseudoCriticalEdges.java new file mode 100644 index 0000000..e43c350 --- /dev/null +++ b/算法周更ç­/class_2023_07_2_week/Code05_FindCriticalAndPseudoCriticalEdges.java @@ -0,0 +1,244 @@ +package class_2023_07_2_week; + +import java.util.Arrays; +import java.util.List; +import java.util.ArrayList; + +// 给你一个 n 个点的带æƒæ— å‘连通图,节点编å·ä¸º 0 到 n-1 +// åŒæ—¶è¿˜æœ‰ä¸€ä¸ªæ•°ç»„ edges ,其中 edges[i] = [fromi, toi, weighti] +// 表示在 fromi å’Œ toi 节点之间有一æ¡å¸¦æƒæ— å‘è¾¹ +// 最å°ç”Ÿæˆæ ‘ (MST) 是给定图中边的一个å­é›† +// 它连接了所有节点且没有环,而且这些边的æƒå€¼å’Œæœ€å° +// 请你找到给定图中最å°ç”Ÿæˆæ ‘的所有关键边和伪关键边 +// 如果从图中删去æŸæ¡è¾¹ï¼Œä¼šå¯¼è‡´æœ€å°ç”Ÿæˆæ ‘çš„æƒå€¼å’Œå¢žåŠ ï¼Œé‚£ä¹ˆæˆ‘们就说它是一æ¡å…³é”®è¾¹ +// 伪关键边则是å¯èƒ½ä¼šå‡ºçŽ°åœ¨æŸäº›æœ€å°ç”Ÿæˆæ ‘中但ä¸ä¼šå‡ºçŽ°åœ¨æ‰€æœ‰æœ€å°ç”Ÿæˆæ ‘中的边 +// 请注æ„,你å¯ä»¥åˆ†åˆ«ä»¥ä»»æ„顺åºè¿”回关键边的下标和伪关键边的下标 +// 测试链接 : https://leetcode.cn/problems/find-critical-and-pseudo-critical-edges-in-minimum-spanning-tree/ +// 本题用到并查集ã€æœ€å°ç”Ÿæˆæ ‘ã€æ±‚è”通图中的桥 +// 并查集ã€æœ€å°ç”Ÿæˆæ ‘ï¼Œåœ¨ä½“ç³»å­¦ä¹ ç­ +// 求桥,在æ¯å‘¨æœ‰è¥å…»çš„大厂算法é¢è¯•é¢˜ï¼Œ2022å¹´10月第1周 +// 链å¼å‰å‘星,2022å¹´10月第1周 +// 务必打好基础,å†æ¥çœ‹è¿™ä¸ªé¢˜çš„è§£æž +// 这个实现打败100%çš„æ交者 +public class Code05_FindCriticalAndPseudoCriticalEdges { + + public static int MAXN = 101; + + public static int MAXM = 201; + + // 边状æ€çš„记录 + // status[ei] = 0,代表ei这个边既ä¸æ˜¯å…³é”®è¾¹ä¹Ÿä¸æ˜¯ä¼ªå…³é”®è¾¹ + // status[ei] = 1,代表ei这个边是伪关键边 + // status[ei] = 2,代表ei这个边是关键边 + public static int[] status = new int[MAXM]; + + // 并查集相关 + public static int[] father = new int[MAXN]; + public static int[] size = new int[MAXN]; + public static int[] help = new int[MAXN]; + public static int sets = 0; + + // 并查集åˆå§‹åŒ– + public static void buildUnoinSet(int n) { + for (int i = 0; i < n; i++) { + father[i] = i; + size[i] = 1; + } + sets = n; + } + + // 并查集å‘上找代表节点 + public static int find(int i) { + int r = 0; + while (i != father[i]) { + help[r++] = i; + i = father[i]; + } + while (r > 0) { + father[help[--r]] = i; + } + return i; + } + + // 并查集åˆå¹¶é›†åˆ + public static void union(int i, int j) { + int fi = find(i); + int fj = find(j); + if (fi != fj) { + if (size[fi] >= size[fj]) { + father[fj] = fi; + size[fi] += size[fj]; + } else { + father[fi] = fj; + size[fj] += size[fi]; + } + sets--; + } + } + + // 边相关 + public static int[][] edges = new int[MAXM][4]; + + public static int m; + + public static void buildEdges(int[][] e) { + for (int i = 0; i < m; i++) { + edges[i][0] = i; + edges[i][1] = e[i][0]; + edges[i][2] = e[i][1]; + edges[i][3] = e[i][2]; + } + Arrays.sort(edges, 0, m, (a, b) -> a[3] - b[3]); + } + + // 通过集åˆç¼–å·å»ºå›¾ç›¸å…³ + // 链å¼å‰å‘星建图 + // 为啥用这玩æ„儿建图?没啥,就是想秀 + public static int[] head = new int[MAXN]; + // int[] to : iå·è¾¹æ˜¯åŽ»å“ªçš„ï¼ + public static int[][] info = new int[MAXM][3]; + public static int[] next = new int[MAXM]; + public static int edgeSize; + + public static void buildGraph(int k) { + for (int i = 0; i < k; i++) { + head[i] = -1; + edgeSize = 0; + } + } + + public static void addEdge(int a, int b, int ei) { + next[edgeSize] = head[a]; + info[edgeSize][0] = ei; + info[edgeSize][1] = a; + info[edgeSize][2] = b; + head[a] = edgeSize++; + } + + // 哈希表相关 + // 一个集åˆï¼Œç»™ä¸€ä¸ªç¼–å· + public static int[] id = new int[MAXN]; + + // 找桥相关 + public static int[] dfn = new int[MAXN]; + public static int[] low = new int[MAXN]; + public static int cnt; + + public static void findBridge(int k) { + Arrays.fill(dfn, 0, k, 0); + Arrays.fill(low, 0, k, 0); + cnt = 0; + for (int init = 0; init < k; init++) { + if (dfn[init] == 0) { + tarjan(init, init, -1, -1); + } + } + } + + public static void tarjan(int init, int cur, int father, int ei) { + dfn[cur] = low[cur] = ++cnt; + for (int i = head[cur]; i != -1; i = next[i]) { + int edgei = info[i][0]; + int nodei = info[i][2]; + if (nodei != father) { + if (dfn[nodei] == 0) { + tarjan(init, nodei, cur, edgei); + low[cur] = Math.min(low[cur], low[nodei]); + } else { + low[cur] = Math.min(low[cur], dfn[nodei]); + } + } + } + if (low[cur] == dfn[cur] && cur != init) { + status[ei] = 2; + } + } + + public static List> findCriticalAndPseudoCriticalEdges(int n, int[][] e) { + m = e.length; + Arrays.fill(status, 0, m, 0); + buildUnoinSet(n); + buildEdges(e); + List bridge = new ArrayList<>(); + List pseudo = new ArrayList<>(); + int start = 0; + while (sets != 1) { + int end = start + 1; + while (end < m && edges[start][3] == edges[end][3]) { + end++; + } + // start....end-1 start... + connect(start, end); + for (int i = start; i < end; i++) { + int ei = edges[i][0]; + if (status[ei] == 2) { + bridge.add(ei); + } else if (status[ei] == 1) { + pseudo.add(ei); + } + union(edges[i][1], edges[i][2]); + } + start = end; + } + return Arrays.asList(bridge, pseudo); + } + + // 大团å­ï¼Œä¸€ä¸ªé›†åˆï¼Œç¼©æˆä¸€ä¸ªç‚¹ + // 当å‰çš„边,[start...end) + // åšå›¾ï¼å¤§å›¢å­çš„å›¾ï¼Œæ‰¾æ¡¥ï¼ + public static void connect(int start, int end) { + for (int i = start; i < end; i++) { + id[find(edges[i][1])] = -1; + id[find(edges[i][2])] = -1; + } + int k = 0; + for (int i = start; i < end; i++) { + if (id[find(edges[i][1])] == -1) { + id[find(edges[i][1])] = k++; + } + if (id[find(edges[i][2])] == -1) { + id[find(edges[i][2])] = k++; + } + } + buildGraph(k); + // 大团å­ï¼Œæœ‰è¾¹ï¼ç”¨é“¾å¼å‰å‘星建图,大团å­çš„å›¾ï¼ + for (int i = start; i < end; i++) { + int index = edges[i][0]; + int a = id[find(edges[i][1])]; + int b = id[find(edges[i][2])]; + if (a != b) { + status[index] = 1; + addEdge(a, b, index); + addEdge(b, a, index); + } + } + findBridge(k); + // 处ç†é‡å¤è¿žæŽ¥ + // 什么是é‡å¤è¿žæŽ¥ï¼Ÿä¸æ˜¯è‡ªå·±æŒ‡å‘自己,那å«è‡ªçŽ¯ + // é‡å¤è¿žæŽ¥æŒ‡çš„是: + // 集åˆa到集åˆb有一æ¡è¾¹ï¼Œè¾¹çš„åºå·æ˜¯p + // 于是,a的邻接表里有(p,b),b的邻接表里有(p,a) + // 集åˆa到集åˆbåˆæœ‰ä¸€æ¡è¾¹ï¼Œè¾¹çš„åºå·æ˜¯t + // 于是,a的邻接表里有(t,b),b的邻接表里有(t,a) + // 那么på’Œt都是é‡å¤é“¾æŽ¥ï¼Œå› ä¸ºå•ç‹¬åˆ æŽ‰p或者t,ä¸ä¼šå½±å“è”通性 + // 而在求桥的模版中,是默认没有é‡å¤é“¾æŽ¥çš„ + // 如果有é‡å¤é“¾æŽ¥å°±ç›´æŽ¥ç”¨æ¨¡ç‰ˆï¼Œé‚£ä¹ˆä¼šå‡ºçŽ°é‡å¤é“¾æŽ¥è¢«è®¤ä¸ºæ˜¯æ¡¥çš„情况 + // 所以这里è¦å•ç‹¬åˆ¤æ–­ï¼Œå¦‚果有é‡å¤é“¾æŽ¥è¢«è®¾ç½®æˆäº†æ¡¥ï¼Œè¦æŠŠå®ƒæ”¹æˆä¼ªå…³é”®è¾¹çš„çŠ¶æ€ + Arrays.sort(info, 0, edgeSize, (a, b) -> a[1] != b[1] ? (a[1] - b[1]) : (a[2] - b[2])); + int right, left = 0; + while (left < edgeSize) { + right = left + 1; + while (right < edgeSize && info[left][1] == info[right][1]) { + right++; + } + for (int i = left + 1; i < right; i++) { + if (info[i][2] == info[i - 1][2]) { + status[info[i][0]] = 1; + status[info[i - 1][0]] = 1; + } + } + left = right; + } + } + +} diff --git a/算法课堂笔记/课堂内容汇总/æ¯å‘¨æœ‰è¥å…»çš„大厂算法é¢è¯•é¢˜(正在直播) b/算法课堂笔记/课堂内容汇总/æ¯å‘¨æœ‰è¥å…»çš„大厂算法é¢è¯•é¢˜(正在直播) index 3eebdc7..dcd15f1 100644 --- a/算法课堂笔记/课堂内容汇总/æ¯å‘¨æœ‰è¥å…»çš„大厂算法é¢è¯•é¢˜(正在直播) +++ b/算法课堂笔记/课堂内容汇总/æ¯å‘¨æœ‰è¥å…»çš„大厂算法é¢è¯•é¢˜(正在直播) @@ -4074,6 +4074,66 @@ forceField[i] = [x,y,side] +第076节 2023å¹´7月2周æµè¡Œç®—æ³•é¢˜ç›®è§£æž + +阿里巴巴走进了装满å®è—çš„è—å®æ´žã€‚è—å®æ´žé‡Œé¢æœ‰Nå †é‡‘å¸ +第i堆金å¸çš„总é‡é‡å’Œæ€»ä»·å€¼åˆ†åˆ«æ˜¯m[i]ã€v[i] +阿里巴巴有一个承é‡é‡ä¸ºT的背包,但并ä¸ä¸€å®šæœ‰åŠžæ³•å°†å…¨éƒ¨çš„金å¸éƒ½è£…进去 +他想装走尽å¯èƒ½å¤šä»·å€¼çš„é‡‘å¸ +所有金å¸éƒ½å¯ä»¥éšæ„分割,分割完的金å¸é‡é‡ä»·å€¼æ¯”(也就是å•ä½ä»·æ ¼ï¼‰ä¸å˜ +请问阿里巴巴最多å¯ä»¥æ‹¿èµ°å¤šå°‘价值的金å¸ï¼Ÿ +测试链接 : https://www.luogu.com.cn/problem/P2240 + +æ¥è‡ªå­—节 +机器人正在玩一个å¤è€çš„基于DOSçš„æ¸¸æˆ +游æˆä¸­æœ‰N+1座建筑,从0到Nç¼–å·ï¼Œä»Žå·¦åˆ°å³æŽ’列 +ç¼–å·ä¸º0的建筑高度为0个å•ä½ï¼Œç¼–å·ä¸ºi的建筑的高度为H(i)个å•ä½ +èµ·åˆï¼Œ 机器人在编å·ä¸º0的建筑处 +æ¯ä¸€æ­¥ï¼Œå®ƒè·³åˆ°ä¸‹ä¸€ä¸ªï¼ˆå³è¾¹ï¼‰å»ºç­‘。å‡è®¾æœºå™¨äººåœ¨ç¬¬k个建筑,且它现在的能é‡å€¼æ˜¯E +下一步它将跳到第个k+1建筑 +它将会得到或者失去正比于与H(k+1)与Eä¹‹å·®çš„èƒ½é‡ +如果 H(k+1) > E 那么机器人就失去H(k+1)-E的能é‡å€¼ï¼Œå¦åˆ™å®ƒå°†å¾—到E-H(k+1)的能é‡å€¼ +游æˆç›®æ ‡æ˜¯åˆ°è¾¾ç¬¬ä¸ªN建筑,在这个过程中,能é‡å€¼ä¸èƒ½ä¸ºè´Ÿæ•°ä¸ªå•ä½ +现在的问题是机器人以多少能é‡å€¼å¼€å§‹æ¸¸æˆï¼Œæ‰å¯ä»¥ä¿è¯æˆåŠŸå®Œæˆæ¸¸æˆ +测试链接 : https://www.nowcoder.com/questionTerminal/7037a3d57bbd4336856b8e16a9cafd71 + +你有 k 个背包。给你一个下标从 0 开始的整数数组 weights +其中 weights[i] 是第 i 个ç å­çš„é‡é‡ã€‚åŒæ—¶ç»™ä½ æ•´æ•° k +请你按照如下规则将所有的ç å­æ”¾è¿› k 个背包。 +没有背包是空的。 +如果第 i 个ç å­å’Œç¬¬ j 个ç å­åœ¨åŒä¸€ä¸ªèƒŒåŒ…里 +那么下标在 i 到 j 之间的所有ç å­éƒ½å¿…须在这åŒä¸€ä¸ªèƒŒåŒ…中 +如果一个背包有下标从 i 到 j 的所有ç å­ï¼Œé‚£ä¹ˆè¿™ä¸ªèƒŒåŒ…的价格是 weights[i] + weights[j] 。 +一个ç å­åˆ†é…方案的 分数 是所有 k 个背包的价格之和。 +请你返回所有分é…方案中,最大分数 与 最å°åˆ†æ•° çš„ 差值 为多少。 +测试链接 : https://leetcode.cn/problems/put-marbles-in-bags/ + +一个公å¸å‡†å¤‡ç»„织一场会议,邀请åå•ä¸Šæœ‰ n ä½å‘˜å·¥ +å…¬å¸å‡†å¤‡äº†ä¸€å¼  圆形 çš„æ¡Œå­ï¼Œå¯ä»¥å下 ä»»æ„æ•°ç›® 的员工 +员工编å·ä¸º 0 到 n - 1 。æ¯ä½å‘˜å·¥éƒ½æœ‰ä¸€ä½ 喜欢 的员工 +æ¯ä½å‘˜å·¥ 当且仅当 他被安排在喜欢员工的æ—边,他æ‰ä¼šå‚加会议 +æ¯ä½å‘˜å·¥å–œæ¬¢çš„员工 ä¸ä¼š 是他自己。 +给你一个下标从 0 开始的整数数组 favorite +其中 favorite[i] 表示第 i ä½å‘˜å·¥å–œæ¬¢çš„员工。请你返回å‚加会议的 最多员工数目 +测试链接 : https://leetcode.cn/problems/maximum-employees-to-be-invited-to-a-meeting/ + +给你一个 n 个点的带æƒæ— å‘连通图,节点编å·ä¸º 0 到 n-1 +åŒæ—¶è¿˜æœ‰ä¸€ä¸ªæ•°ç»„ edges ,其中 edges[i] = [fromi, toi, weighti] +表示在 fromi å’Œ toi 节点之间有一æ¡å¸¦æƒæ— å‘è¾¹ +最å°ç”Ÿæˆæ ‘ (MST) 是给定图中边的一个å­é›† +它连接了所有节点且没有环,而且这些边的æƒå€¼å’Œæœ€å° +请你找到给定图中最å°ç”Ÿæˆæ ‘的所有关键边和伪关键边 +如果从图中删去æŸæ¡è¾¹ï¼Œä¼šå¯¼è‡´æœ€å°ç”Ÿæˆæ ‘çš„æƒå€¼å’Œå¢žåŠ ï¼Œé‚£ä¹ˆæˆ‘们就说它是一æ¡å…³é”®è¾¹ +伪关键边则是å¯èƒ½ä¼šå‡ºçŽ°åœ¨æŸäº›æœ€å°ç”Ÿæˆæ ‘中但ä¸ä¼šå‡ºçŽ°åœ¨æ‰€æœ‰æœ€å°ç”Ÿæˆæ ‘中的边 +请注æ„,你å¯ä»¥åˆ†åˆ«ä»¥ä»»æ„顺åºè¿”回关键边的下标和伪关键边的下标 +测试链接 : https://leetcode.cn/problems/find-critical-and-pseudo-critical-edges-in-minimum-spanning-tree/ + + + + + + +