diff --git a/MCA算法突击课/第03期/mca_05/Code01_BoatsToSavePeople.java b/MCA算法突击课/第03期/mca_05/Code01_BoatsToSavePeople.java new file mode 100644 index 0000000..4ef0d51 --- /dev/null +++ b/MCA算法突击课/第03期/mca_05/Code01_BoatsToSavePeople.java @@ -0,0 +1,33 @@ +package 第03期.mca_05; + +import java.util.Arrays; + +// 给定一个正数数组arr,代表若干人的体重 +// 再给定一个正数limit,表示所有船共同拥有的载重量 +// 每艘船最多坐两人,且不能超过载重 +// 想让所有的人同时过河,并且用最好的分配方法让船尽量少 +// 返回最少的船数 +// 测试链接 : https://leetcode.com/problems/boats-to-save-people/ +public class Code01_BoatsToSavePeople { + + // 首尾双指针的解法 + public static int numRescueBoats2(int[] people, int limit) { + Arrays.sort(people); + int ans = 0; + int l = 0; + int r = people.length - 1; + int sum = 0; + while (l <= r) { + sum = l == r ? people[l] : people[l] + people[r]; + if (sum > limit) { + r--; + } else { + l++; + r--; + } + ans++; + } + return ans; + } + +} diff --git a/MCA算法突击课/第03期/mca_05/Code02_TrappingRainWater.java b/MCA算法突击课/第03期/mca_05/Code02_TrappingRainWater.java new file mode 100644 index 0000000..8f76677 --- /dev/null +++ b/MCA算法突击课/第03期/mca_05/Code02_TrappingRainWater.java @@ -0,0 +1,30 @@ +package 第03期.mca_05; + +// 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图 +// 计算按此排列的柱子,下雨之后能接多少雨水 +// 本题测试链接 : https://leetcode.cn/problems/trapping-rain-water/ +public class Code02_TrappingRainWater { + + public static int trap(int[] arr) { + if (arr == null || arr.length < 2) { + return 0; + } + int N = arr.length; + int L = 1; + int leftMax = arr[0]; + int R = N - 2; + int rightMax = arr[N - 1]; + int water = 0; + while (L <= R) { + if (leftMax <= rightMax) { + water += Math.max(0, leftMax - arr[L]); + leftMax = Math.max(leftMax, arr[L++]); + } else { + water += Math.max(0, rightMax - arr[R]); + rightMax = Math.max(rightMax, arr[R--]); + } + } + return water; + } + +} diff --git a/MCA算法突击课/第03期/mca_05/Code03_LongestSumSubArrayLength.java b/MCA算法突击课/第03期/mca_05/Code03_LongestSumSubArrayLength.java new file mode 100644 index 0000000..f181755 --- /dev/null +++ b/MCA算法突击课/第03期/mca_05/Code03_LongestSumSubArrayLength.java @@ -0,0 +1,30 @@ +package 第03期.mca_05; + +import java.util.HashMap; + +// 给定一个数组 nums 和一个目标值 k,找到和等于 k 的最长连续子数组长度 +// 如果不存在任意一个符合要求的子数组,则返回 0 +// 测试链接 : https://leetcode.cn/problems/maximum-size-subarray-sum-equals-k/ +public class Code03_LongestSumSubArrayLength { + + public int maxSubArrayLen(int[] arr, int k) { + if (arr == null || arr.length == 0) { + return 0; + } + HashMap map = new HashMap(); + map.put(0, -1); + int len = 0; + int sum = 0; + for (int i = 0; i < arr.length; i++) { + sum += arr[i]; + if (map.containsKey(sum - k)) { + len = Math.max(i - map.get(sum - k), len); + } + if (!map.containsKey(sum)) { + map.put(sum, i); + } + } + return len; + } + +} diff --git a/MCA算法突击课/第03期/mca_05/Code04_FriendCircles.java b/MCA算法突击课/第03期/mca_05/Code04_FriendCircles.java deleted file mode 100644 index c63a059..0000000 --- a/MCA算法突击课/第03期/mca_05/Code04_FriendCircles.java +++ /dev/null @@ -1,78 +0,0 @@ -package 第03期.mca_05; - -// 有 n 个城市,其中一些彼此相连,另一些没有相连 -// 如果城市 a 与城市 b 直接相连 -// 且城市 b 与城市 c 直接相连 -// 那么城市 a 与城市 c 间接相连 -// 省份 是一组直接或间接相连的城市 -// 组内不含其他没有相连的城市。 -// 给你一个 n x n 的矩阵 isConnected -// 其中 isConnected[i][j] = 1 表示第 i 个城市和第 j 个城市直接相连 -// 而 isConnected[i][j] = 0 表示二者不直接相连。 -// 返回矩阵中 省份 的数量。 -// 测试链接:https://leetcode.cn/problems/friend-circles/ -public class Code04_FriendCircles { - - public static int findCircleNum(int[][] M) { - int N = M.length; - UnionFind uf = new UnionFind(N); - for (int i = 0; i < N; i++) { - for (int j = i + 1; j < N; j++) { - if (M[i][j] == 1) { // i和j互相认识 - uf.union(i, j); - } - } - } - return uf.sets(); - } - - public static class UnionFind { - private int[] father; - private int[] size; - private int[] help; - private int sets; - - public UnionFind(int N) { - father = new int[N]; - size = new int[N]; - help = new int[N]; - sets = N; - for (int i = 0; i < N; i++) { - father[i] = i; - size[i] = 1; - } - } - - private int find(int i) { - int hi = 0; - while (i != father[i]) { - help[hi++] = i; - i = father[i]; - } - for (hi--; hi >= 0; hi--) { - father[help[hi]] = i; - } - return i; - } - - public void union(int i, int j) { - int f1 = find(i); - int f2 = find(j); - if (f1 != f2) { - if (size[f1] >= size[f2]) { - size[f1] += size[f2]; - father[f2] = f1; - } else { - size[f2] += size[f1]; - father[f1] = f2; - } - sets--; - } - } - - public int sets() { - return sets; - } - } - -} diff --git a/MCA算法突击课/第03期/mca_05/Code04_LongestWellPerformingInterval.java b/MCA算法突击课/第03期/mca_05/Code04_LongestWellPerformingInterval.java new file mode 100644 index 0000000..8a4cfa9 --- /dev/null +++ b/MCA算法突击课/第03期/mca_05/Code04_LongestWellPerformingInterval.java @@ -0,0 +1,65 @@ +package 第03期.mca_05; + +import java.util.Arrays; +import java.util.HashMap; + +// 给你一份工作时间表 hours,上面记录着某一位员工每天的工作小时数。 +// 我们认为当员工一天中的工作小时数大于 8 小时的时候,那么这一天就是「劳累的一天」。 +// 所谓「表现良好的时间段」,意味在这段时间内,「劳累的天数」是严格 大于「不劳累的天数」。 +// 请你返回「表现良好时间段」的最大长度。 +// 测试链接 : https://leetcode.cn/problems/longest-well-performing-interval/ +public class Code04_LongestWellPerformingInterval { + + // 哈希表 + public static int longestWPI1(int[] hours) { + // key : 某个前缀和 + // value : 这个前缀和最早出现的位置 + HashMap map = new HashMap<>(); + // 0这个前缀和,最早出现在哪?一个数也没有的时候 + map.put(0, -1); + int ans = 0; + int sum = 0; + for (int i = 0; i < hours.length; i++) { + sum += hours[i] > 8 ? 1 : -1; + if (sum > 0) { + // 0...i i+1 + ans = i + 1; + } else { + // sum = -4 + // -5最早出现在哪 j j+1...i + if (map.containsKey(sum - 1)) { + ans = Math.max(ans, i - map.get(sum - 1)); + } + } + if (!map.containsKey(sum)) { + map.put(sum, i); + } + } + return ans; + } + + // 数组替代哈希表 + public static int longestWPI2(int[] hours) { + int n = hours.length; + int[] early = new int[(n << 1) + 1]; + Arrays.fill(early, -2); + early[0 + n] = -1; + int ans = 0; + int sum = 0; + for (int i = 0; i < hours.length; i++) { + sum += hours[i] > 8 ? 1 : -1; + if (sum > 1) { + ans = i + 1; + } else { + if (sum - 1 + n >= 0 && early[sum - 1 + n] != -2) { + ans = Math.max(ans, i - early[sum - 1 + n]); + } + } + if (early[sum + n] == -2) { + early[sum + n] = i; + } + } + return ans; + } + +} diff --git a/MCA算法突击课/第03期/mca_05/Code03_UnionFind.java b/MCA算法突击课/第03期/mca_05/Code05_UnionFind.java similarity index 94% rename from MCA算法突击课/第03期/mca_05/Code03_UnionFind.java rename to MCA算法突击课/第03期/mca_05/Code05_UnionFind.java index 9f5c733..ab77f12 100644 --- a/MCA算法突击课/第03期/mca_05/Code03_UnionFind.java +++ b/MCA算法突击课/第03期/mca_05/Code05_UnionFind.java @@ -13,7 +13,7 @@ import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.StreamTokenizer; -public class Code03_UnionFind { +public class Code05_UnionFind { public static int MAXN = 1000001; diff --git a/MCA算法突击课/第03期/mca_05/Code06_MostStonesRemovedWithSameRowOrColumn.java b/MCA算法突击课/第03期/mca_05/Code06_MostStonesRemovedWithSameRowOrColumn.java new file mode 100644 index 0000000..8c5fa6b --- /dev/null +++ b/MCA算法突击课/第03期/mca_05/Code06_MostStonesRemovedWithSameRowOrColumn.java @@ -0,0 +1,87 @@ +package 第03期.mca_05; + +import java.util.HashMap; + +// n块石头放置在二维平面中的一些整数坐标点上 +// 每个坐标点上最多只能有一块石头 +// 如果一块石头的 同行或者同列 上有其他石头存在,那么就可以移除这块石头。 +// 给你一个长度为 n 的数组 stones , +// 其中 stones[i] = [xi, yi] 表示第 i 块石头的位置, +// 返回 可以移除的石子 的最大数量。 +// 测试链接 : https://leetcode.cn/problems/most-stones-removed-with-same-row-or-column/ +public class Code06_MostStonesRemovedWithSameRowOrColumn { + + public static int removeStones(int[][] stones) { + int n = stones.length; + HashMap rowPre = new HashMap(); + HashMap colPre = new HashMap(); + UnionFind uf = new UnionFind(n); + for (int i = 0; i < n; i++) { + int x = stones[i][0]; + int y = stones[i][1]; + if (!rowPre.containsKey(x)) { + rowPre.put(x, i); + } else { + uf.union(i, rowPre.get(x)); + } + if (!colPre.containsKey(y)) { + colPre.put(y, i); + } else { + uf.union(i, colPre.get(y)); + } + } + return n - uf.sets(); + } + + public static class UnionFind { + + public int[] father; + public int[] size; + public int[] help; + public int sets; + + public UnionFind(int n) { + father = new int[n]; + size = new int[n]; + help = new int[n]; + for (int i = 0; i < n; i++) { + father[i] = i; + size[i] = 1; + } + sets = n; + } + + private int find(int i) { + int hi = 0; + while (i != father[i]) { + help[hi++] = i; + i = father[i]; + } + while (hi != 0) { + father[help[--hi]] = i; + } + return i; + } + + public 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 int sets() { + return sets; + } + + } + +} diff --git a/MCA算法突击课/第03期/mca_05/Code05_CouplesHoldingHands.java b/MCA算法突击课/第03期/mca_05/Code07_CouplesHoldingHands.java similarity index 97% rename from MCA算法突击课/第03期/mca_05/Code05_CouplesHoldingHands.java rename to MCA算法突击课/第03期/mca_05/Code07_CouplesHoldingHands.java index db0aba2..50b4bcb 100644 --- a/MCA算法突击课/第03期/mca_05/Code05_CouplesHoldingHands.java +++ b/MCA算法突击课/第03期/mca_05/Code07_CouplesHoldingHands.java @@ -6,7 +6,7 @@ package 第03期.mca_05; // 返回 最少交换座位的次数,以便每对情侣可以并肩坐在一起 // 每次交换可选择任意两人,让他们站起来交换座位 // 测试链接 : https://leetcode.cn/problems/couples-holding-hands/ -public class Code05_CouplesHoldingHands { +public class Code07_CouplesHoldingHands { public int minSwapsCouples(int[] row) { int n = row.length; diff --git a/MCA算法突击课/第03期/mca_05/Code07_LRUCache.java b/MCA算法突击课/第03期/mca_05/Code08_LRUCache.java similarity index 98% rename from MCA算法突击课/第03期/mca_05/Code07_LRUCache.java rename to MCA算法突击课/第03期/mca_05/Code08_LRUCache.java index 9404699..f1512f9 100644 --- a/MCA算法突击课/第03期/mca_05/Code07_LRUCache.java +++ b/MCA算法突击课/第03期/mca_05/Code08_LRUCache.java @@ -3,7 +3,7 @@ package 第03期.mca_05; import java.util.HashMap; // 测试链接 : https://leetcode.cn/problems/lru-cache/ -public class Code07_LRUCache { +public class Code08_LRUCache { // 提交以下这个类 public class LRUCache { diff --git a/MCA算法突击课/第03期/ppt/key/第05节 .key b/MCA算法突击课/第03期/ppt/key/第05节 .key new file mode 100644 index 0000000..d81d84f Binary files /dev/null and b/MCA算法突击课/第03期/ppt/key/第05节 .key differ diff --git a/MCA算法突击课/第03期/ppt/powerpoint/第05节 .pptx b/MCA算法突击课/第03期/ppt/powerpoint/第05节 .pptx new file mode 100644 index 0000000..296de59 Binary files /dev/null and b/MCA算法突击课/第03期/ppt/powerpoint/第05节 .pptx differ