modify code

master
algorithmzuo 1 year ago
parent 6a93df978f
commit 1cece71f21

@ -7,11 +7,11 @@ import java.util.Arrays;
// 每艘船最多坐两人,且不能超过载重
// 想让所有的人同时过河,并且用最好的分配方法让船尽量少
// 返回最少的船数
// 测试链接 : https://leetcode.com/problems/boats-to-save-people/
// 测试链接 : https://leetcode.cn/problems/boats-to-save-people/
public class Code01_BoatsToSavePeople {
// 首尾双指针的解法
public static int numRescueBoats2(int[] people, int limit) {
public static int numRescueBoats(int[] people, int limit) {
Arrays.sort(people);
int ans = 0;
int l = 0;

@ -5,6 +5,30 @@ package 第03期.mca_05;
// 本题测试链接 : https://leetcode.cn/problems/trapping-rain-water/
public class Code02_TrappingRainWater {
// 辅助数组的
public static int zuo(int[] arr) {
int n = arr.length;
if (n < 3) {
return 0;
}
int[] leftMax = new int[n];
leftMax[0] = arr[0];
for (int i = 1; i < n; i++) {
leftMax[i] = Math.max(leftMax[i - 1], arr[i]);
}
int[] rightMax = new int[n];
rightMax[n - 1] = arr[n - 1];
for (int i = n - 2; i >= 0; i--) {
rightMax[i] = Math.max(rightMax[i + 1], arr[i]);
}
int ans = 0;
for (int i = 1; i < n - 1; i++) {
ans += Math.max(Math.min(leftMax[i - 1], rightMax[i + 1]) - arr[i], 0);
}
return ans;
}
// 首尾双指针
public static int trap(int[] arr) {
if (arr == null || arr.length < 2) {
return 0;

@ -11,20 +11,51 @@ public class Code03_LongestSumSubArrayLength {
if (arr == null || arr.length == 0) {
return 0;
}
// key : 某个前缀和 value : 最早位置
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
// 非常重要 !
map.put(0, -1);
int len = 0;
int ans = 0;
int sum = 0;
for (int i = 0; i < arr.length; i++) {
// sum : 0.....i 整体的和
sum += arr[i];
if (map.containsKey(sum - k)) {
len = Math.max(i - map.get(sum - k), len);
// 0.......730 1000 k = 100
// 0...17 900
// 18..730
// 长度 = i - 最早位置
ans = Math.max(i - map.get(sum - k), ans);
}
if (!map.containsKey(sum)) {
map.put(sum, i);
}
}
return len;
return ans;
}
public int maxSubArrayLen2(int[] arr, int k) {
if (arr == null || arr.length == 0) {
return 0;
}
// key : 某个前缀和 value : 最早位置
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
int ans = 0;
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
if (sum == k) {
ans = Math.max(i + 1, ans);
} else {
if (map.containsKey(sum - k)) {
ans = Math.max(i - map.get(sum - k), ans);
}
}
if (!map.containsKey(sum)) {
map.put(sum, i);
}
}
return ans;
}
}

@ -3,7 +3,7 @@ package 第03期.mca_05;
import java.util.HashMap;
// 测试链接 : https://leetcode.cn/problems/lru-cache/
public class Code08_LRUCache {
public class Code05_LRUCache {
// 提交以下这个类
public class LRUCache {
@ -43,28 +43,28 @@ public class Code08_LRUCache {
}
}
public void moveNodeToTail(Node node) {
if (tail == node) {
public void moveNodeToTail(Node x) {
if (tail == x) {
return;
}
if (head == node) {
head = node.next;
if (head == x) { // x在头部
head = x.next;
head.last = null;
} else {
node.last.next = node.next;
node.next.last = node.last;
x.last.next = x.next;
x.next.last = x.last;
}
node.last = tail;
node.next = null;
this.tail.next = node;
this.tail = node;
x.last = tail;
x.next = null;
tail.next = x;
tail = x;
}
public Node removeHead() {
if (head == null) {
return null;
}
Node ans = this.head;
Node ans = head;
if (head == tail) {
head = null;
tail = null;
@ -78,8 +78,11 @@ public class Code08_LRUCache {
}
// A -> Node
private HashMap<Integer, Node> keyNodeMap;
// Node 串成的双向链表
private DoubleLinkedList nodeList;
// 这个结构的容量!
private final int capacity;
public LRUCache(int cap) {
@ -97,12 +100,16 @@ public class Code08_LRUCache {
return -1;
}
// A 23
public void put(int key, int value) {
if (keyNodeMap.containsKey(key)) {
Node node = keyNodeMap.get(key);
node.val = value;
nodeList.moveNodeToTail(node);
} else {
// 之前没有A的记录新增!
// 1) 结构满了
// 2) 结构没有满
if (keyNodeMap.size() == capacity) {
removeMostUnusedCache();
}

@ -1,7 +1,7 @@
package 03.mca_05;
package 03.mca_06;
// 并查集实现
// 测试链接 : https://www.nowcoder.com/questionTerminal/e7ed657974934a30b2010046536a5372
// 请务必理解这个文件的实现,而且还提供了测试链接
// 提交如下的code并把主类名改成"Main"
// 在测试链接里可以直接通过
// 请同学们务必参考如下代码中关于输入、输出的处理
@ -13,7 +13,7 @@ import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
public class Code05_UnionFind {
public class Code01_UnionFind {
public static int MAXN = 1000001;

@ -1,4 +1,4 @@
package 03.mca_05;
package 03.mca_06;
import java.util.HashMap;
@ -9,7 +9,7 @@ import java.util.HashMap;
// 其中 stones[i] = [xi, yi] 表示第 i 块石头的位置,
// 返回 可以移除的石子 的最大数量。
// 测试链接 : https://leetcode.cn/problems/most-stones-removed-with-same-row-or-column/
public class Code06_MostStonesRemovedWithSameRowOrColumn {
public class Code02_MostStonesRemovedWithSameRowOrColumn {
public static int removeStones(int[][] stones) {
int n = stones.length;

@ -1,4 +1,4 @@
package 03.mca_05;
package 03.mca_06;
// n对情侣坐在连续排列的 2n 个座位上,想要牵到对方的手
// 人和座位由一个整数数组 row 表示,其中 row[i] 是坐在第 i 个座位上的人的ID
@ -6,7 +6,7 @@ package 第03期.mca_05;
// 返回 最少交换座位的次数,以便每对情侣可以并肩坐在一起
// 每次交换可选择任意两人,让他们站起来交换座位
// 测试链接 : https://leetcode.cn/problems/couples-holding-hands/
public class Code07_CouplesHoldingHands {
public class Code03_CouplesHoldingHands {
public int minSwapsCouples(int[] row) {
int n = row.length;

@ -0,0 +1,89 @@
package 03.mca_06;
// 根据入度来求拓扑排序,牛客网的测试数据
// 测试链接 : https://www.nowcoder.com/questionTerminal/88f7e156ca7d43a1a535f619cd3f495c
// 请同学们务必参考如下代码中关于输入、输出的处理
// 这是输入输出处理效率很高的写法
// 提交以下所有代码把主类名改成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.ArrayList;
import java.util.Arrays;
public class Code04_TopologicalSort {
public static int MAXN = 200001;
public static int[] queue = new int[MAXN];
public static int[] indegree = new int[MAXN];
public static int[] ans = new int[MAXN];
public static int n, m, from, to;
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();
m = (int) in.nval;
ArrayList<ArrayList<Integer>> graph = new ArrayList<>();
for (int i = 0; i <= n; i++) {
graph.add(new ArrayList<>());
}
for (int i = 0; i < m; i++) {
in.nextToken();
from = (int) in.nval;
in.nextToken();
to = (int) in.nval;
graph.get(from).add(to);
}
if (!topoSort(graph)) {
out.println(-1);
} else {
for (int i = 0; i < n - 1; i++) {
out.print(ans[i] + " ");
}
out.println(ans[n - 1]);
}
out.flush();
}
}
// 有拓扑排序返回true
// 没有拓扑排序返回false
public static boolean topoSort(ArrayList<ArrayList<Integer>> graph) {
Arrays.fill(indegree, 1, n + 1, 0);
for (ArrayList<Integer> nexts : graph) {
for (int next : nexts) {
indegree[next]++;
}
}
int l = 0;
int r = 0;
for (int i = 1; i <= n; i++) {
if (indegree[i] == 0) {
queue[r++] = i;
}
}
int cnt = 0;
while (l < r) {
int cur = queue[l++];
ans[cnt++] = cur;
for (int next : graph.get(cur)) {
if (--indegree[next] == 0) {
queue[r++] = next;
}
}
}
return cnt == n;
}
}

@ -0,0 +1,99 @@
package 03.mca_06;
// 课上没讲这个实现
// 因为是一样的都是用Kruskal算法实现最小生成树只不过是牛客网的测试数据
// 测试链接 : https://www.nowcoder.com/questionTerminal/c23eab7bb39748b6b224a8a3afbe396b
// 请同学们务必参考如下代码中关于输入、输出的处理
// 这是输入输出处理效率很高的写法
// 提交以下所有代码把主类名改成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 Code05_Kruskal {
public static int MAXM = 100001;
public static int[][] edges = new int[MAXM][3];
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) {
int n = (int) in.nval;
in.nextToken();
int m = (int) in.nval;
for (int i = 0; i < m; i++) {
in.nextToken();
edges[i][0] = (int) in.nval;
in.nextToken();
edges[i][1] = (int) in.nval;
in.nextToken();
edges[i][2] = (int) in.nval;
}
Arrays.sort(edges, 0, m, (a, b) -> a[2] - b[2]);
build(n);
int ans = 0;
for (int[] edge : edges) {
if (union(edge[0], edge[1])) {
ans += edge[2];
}
}
out.println(ans);
out.flush();
}
}
// 下面是并查集结构
public static int MAXN = 10001;
public static int[] father = new int[MAXN];
public static int[] size = new int[MAXN];
public static int[] help = new int[MAXN];
public static void build(int n) {
for (int i = 1; i <= n; i++) {
father[i] = i;
size[i] = 1;
}
}
private static int find(int i) {
int size = 0;
while (i != father[i]) {
help[size++] = i;
i = father[i];
}
while (size > 0) {
father[help[--size]] = i;
}
return i;
}
// 如果i和j原本是一个集合返回false
// 如果i和j不是一个集合合并然后返回true
public static boolean 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];
}
return true;
} else {
return false;
}
}
}

@ -0,0 +1,90 @@
package 03.mca_06;
import java.util.Arrays;
// 村里面一共有 n 栋房子
// 我们希望通过建造水井和铺设管道来为所有房子供水。
// 对于每个房子 i我们有两种可选的供水方案
// 一种是直接在房子内建造水井,
// 成本为 wells[i - 1](注意 -1 ,因为 索引从0开始)
// 另一种是从另一口井铺设管道引水,
// 数组 pipes 给出了在房子间铺设管道的成本
// 其中每个 pipes[j] = [house1j, house2j, costj]
// 代表用管道将 house1j 和 house2j连接在一起的成本
// 连接是双向的
// 请返回 为所有房子都供水的最低总成本
// 测试链接 : https://leetcode.cn/problems/optimize-water-distribution-in-a-village/
public class Code06_OptimizeWaterDistributionInVillage {
public static int MAXN = 10010;
public static int[][] edges = new int[MAXN << 1][3];
public static int esize;
public static int[] father = new int[MAXN];
public static int[] size = new int[MAXN];
public static int[] help = new int[MAXN];
public static void build(int n) {
for (int i = 0; i <= n; i++) {
father[i] = i;
size[i] = 1;
}
}
public static int find(int i) {
int s = 0;
while (i != father[i]) {
help[s++] = i;
i = father[i];
}
while (s > 0) {
father[help[--s]] = i;
}
return i;
}
public static boolean union(int i, int j) {
int f1 = find(i);
int f2 = find(j);
if (f1 != f2) {
if (size[f1] >= size[f2]) {
father[f2] = f1;
size[f1] += size[f2];
} else {
father[f1] = f2;
size[f2] += size[f1];
}
return true;
} else {
return false;
}
}
public static int minCostToSupplyWater(int n, int[] wells, int[][] pipes) {
esize = 0;
for (int i = 0; i < n; i++, esize++) {
edges[esize][0] = 0;
edges[esize][1] = i + 1;
edges[esize][2] = wells[i];
}
for (int i = 0; i < pipes.length; i++, esize++) {
edges[esize][0] = pipes[i][0];
edges[esize][1] = pipes[i][1];
edges[esize][2] = pipes[i][2];
}
Arrays.sort(edges, 0, esize, (a, b) -> a[2] - b[2]);
build(n);
int ans = 0;
for (int i = 0; i < esize; i++) {
if (union(edges[i][0], edges[i][1])) {
ans += edges[i][2];
}
}
return ans;
}
}

@ -0,0 +1,41 @@
package 03.mca_06;
import java.util.ArrayList;
import java.util.PriorityQueue;
// Dijkstra算法
// leetcode 743题可以用这道题来练习Dijkstra算法
// 测试链接 : https://leetcode.com/problems/network-delay-time
public class Code07_NetworkDelayTime {
public static int networkDelayTime(int[][] times, int n, int k) {
ArrayList<ArrayList<int[]>> nexts = new ArrayList<>();
for (int i = 0; i <= n; i++) {
nexts.add(new ArrayList<>());
}
for (int[] delay : times) {
nexts.get(delay[0]).add(new int[] { delay[1], delay[2] });
}
PriorityQueue<int[]> heap = new PriorityQueue<>((a, b) -> a[1] - b[1]);
heap.add(new int[] { k, 0 });
boolean[] used = new boolean[n + 1];
int num = 0;
int max = 0;
while (!heap.isEmpty() && num < n) {
int[] record = heap.poll();
int cur = record[0];
int delay = record[1];
if (used[cur]) {
continue;
}
used[cur] = true;
num++;
max = Math.max(max, delay);
for (int[] next : nexts.get(cur)) {
heap.add(new int[] { next[0], delay + next[1] });
}
}
return num < n ? -1 : max;
}
}
Loading…
Cancel
Save