From e39312c69a930c46b62673e1434e819a71962ead Mon Sep 17 00:00:00 2001 From: xiaotiancai893661742 <46739364+xiaotiancai893661742@users.noreply.github.com> Date: Mon, 1 Aug 2022 19:44:18 +0800 Subject: [PATCH] 123 --- .../zuolaos/jichuban/Code10_各种排序.java | 1 - .../zuolaos/jichuban/Code13_堆排序.java | 81 ++++-- .../zuolaos/jichuban/Code17_贪心算法.java | 194 +++++++++++++ .../zuolaos/jichuban/Code18_并查集.java | 269 ++++++++++++++++++ 4 files changed, 528 insertions(+), 17 deletions(-) create mode 100644 src/test/java/zuolaos/jichuban/Code17_贪心算法.java create mode 100644 src/test/java/zuolaos/jichuban/Code18_并查集.java diff --git a/src/test/java/zuolaos/jichuban/Code10_各种排序.java b/src/test/java/zuolaos/jichuban/Code10_各种排序.java index 366329b..59ac3ff 100644 --- a/src/test/java/zuolaos/jichuban/Code10_各种排序.java +++ b/src/test/java/zuolaos/jichuban/Code10_各种排序.java @@ -1,7 +1,6 @@ package zuolaos.jichuban; import java.lang.reflect.Method; -import java.lang.reflect.Proxy; public class Code10_各种排序 { diff --git a/src/test/java/zuolaos/jichuban/Code13_堆排序.java b/src/test/java/zuolaos/jichuban/Code13_堆排序.java index 1494a02..4caf232 100644 --- a/src/test/java/zuolaos/jichuban/Code13_堆排序.java +++ b/src/test/java/zuolaos/jichuban/Code13_堆排序.java @@ -1,5 +1,7 @@ package zuolaos.jichuban; +import java.util.Arrays; +import java.util.Comparator; import java.util.PriorityQueue; public class Code13_堆排序 { @@ -17,7 +19,7 @@ public class Code13_堆排序 { System.out.println(myMaxHeap.pop()); int arr[] = {8, 1, 2, 3, 4, 5, 6, 70}; - MyMinHeap myMinHeap = new MyMinHeap(arr); + MyMinHeap myMinHeap = new MyMinHeap(); System.out.println(myMinHeap.pop()); System.out.println(myMinHeap.pop()); System.out.println(myMinHeap.pop()); @@ -38,23 +40,21 @@ class MaxMoveK { for (; index < Math.min(k, arr.length - 1); index++) { heap.add(arr[index]); } - int arrIndex=0; + int arrIndex = 0; for (; index < arr.length; index++) { heap.add(arr[index]); - arr[arrIndex++]=heap.poll(); + arr[arrIndex++] = heap.poll(); } - while (!heap.isEmpty()){ - arr[arrIndex++]=heap.poll(); + while (!heap.isEmpty()) { + arr[arrIndex++] = heap.poll(); } } - - } class MyMinHeap { private int[] heap; - private final int limit; + private int limit; private int heapSize; public MyMinHeap(int limit) { @@ -63,15 +63,25 @@ class MyMinHeap { heapSize = 0; } - public MyMinHeap(int[] heap) { - this.heap = heap; - this.limit = heap.length; - this.heapSize = heap.length; - for (int i = heapSize - 1; i >= 0; i--) { - helpify(heap, i); + public MyMinHeap() { + } + + public void heapSort(int[] arr) { + if (arr == null || arr.length < 2) { + return; + } + int heapSize = arr.length; + for (int i = arr.length / 2; i >= 0; i--) { + helpify(arr, i, heapSize); + } + + for (int i = 0; i < arr.length; i++) { + swap(arr, 0, --heapSize); + helpify(arr, 0, heapSize); } } + public boolean isEmpty() { return this.heapSize == 0; } @@ -91,7 +101,7 @@ class MyMinHeap { public int pop() { int ans = heap[0]; swap(heap, 0, --heapSize); - helpify(heap, 0); + helpify(heap, 0, heapSize); return ans; } @@ -105,7 +115,7 @@ class MyMinHeap { } //在index位置不断的下沉 - public void helpify(int[] arr, int index) { + public void helpify(int[] arr, int index, int heapSize) { int left = 2 * index + 1; while (left < heapSize) { int least = left + 1 < heapSize && arr[left + 1] < arr[left] ? left + 1 : left; @@ -141,6 +151,7 @@ class MyMaxHeap { heapSize = 0; } + public boolean isEmpty() { return this.heapSize == 0; } @@ -199,6 +210,44 @@ class MyMaxHeap { } +class 最大重合线段数 { + private class Line { + int start; + int end; + + public Line(int start, int end) { + this.start = start; + this.end = end; + } + } + + public int process(int[][] m) { + Line[] lines = new Line[m.length]; + for (int i = 0; i < m.length; i++) { + lines[i] = new Line(m[i][0], m[i][1]); + } + Arrays.sort(lines, new Comparator() { + @Override + public int compare(Line o1, Line o2) { + return o1.start - o2.start; + } + }); + + //已线段start结尾的 线段重合个数 自己算一个 + PriorityQueue queue = new PriorityQueue<>(); + int max=0; + for (int i = 0; i < lines.length; i++) { + while (!queue.isEmpty() && queue.peek()<=lines[i].start){ + queue.poll(); + } + queue.add(lines[i].end); + max=Math.max(max,queue.size()); + } + return max; + } +} + + diff --git a/src/test/java/zuolaos/jichuban/Code17_贪心算法.java b/src/test/java/zuolaos/jichuban/Code17_贪心算法.java new file mode 100644 index 0000000..2efc56f --- /dev/null +++ b/src/test/java/zuolaos/jichuban/Code17_贪心算法.java @@ -0,0 +1,194 @@ +package zuolaos.jichuban; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.PriorityQueue; +import java.util.TreeSet; + +public class Code17_贪心算法 { +} + +class 在时间段会议最多 { + + private class Program { + int start; + int end; + + public Program(int start, int end) { + this.start = start; + this.end = end; + } + } + + //贪心解法 + public int process(Program[] programs) { + Arrays.sort(programs, new Comparator() { + @Override + public int compare(Program o1, Program o2) { + return o1.end - o2.end; + } + }); + int start = 0; + int ans = 0; + for (Program program : programs) { + if (program.start >= start) { + ans++; + start = program.end; + } + } + return ans; + } + + + //暴力解法 + public int baoli(Program[] programs, int done, int timeLine) { + //无会议室可以选择 + if (programs == null || programs.length == 0) { + return 0; + } + + //已经选择的 + int max = done; + for (int i = 0; i < programs.length; i++) { + if (programs[i].start >= timeLine) { + //删除集合返回集合 + Program[] newprograms = null; + int don = baoli(newprograms, done + 1, programs[i].end); + max = Math.max(done, don); + } + } + return max; + } +} + + +class 数组中按照字典序排列 { + //贪心解法 + public String process(String[] strs) { + Arrays.sort(strs, new Comparator() { + @Override + public int compare(String o1, String o2) { + return (o1 + o2).compareTo(o2 + o1); + } + }); + String ans = ""; + for (String str : strs) { + ans += str; + } + return ans; + } + + //暴力解法 + public TreeSet baoli(String[] strs) { + TreeSet ans = new TreeSet<>(); + if (strs == null || strs.length == 0) { + ans.add(""); + return ans; + } + + for (int i = 0; i < strs.length; i++) { + String first = strs[i]; + //删除返回新数组 + String[] newstrs = null; + TreeSet baoli = baoli(newstrs); + for (String next : baoli) { + ans.add(first + next); + } + } + return ans; + + } + +} + + +class 金条分割的最小代价 { + + public int process(int[] arr) { + PriorityQueue queue = new PriorityQueue<>(); + for (int i : arr) { + queue.add(i); + } + int sum = 0; + int cur = 0; + while (queue.size() > 1) { + cur = queue.poll() + queue.poll(); + sum += cur; + queue.add(cur); + } + return sum; + } +} + +class 有限资金获得最大利润 { + + private class Program { + int c; //成本 + int p; //纯利润 + + public Program(int c, int p) { + this.c = c; + this.p = p; + } + } + + public int process(int K, int W, int[] c, int[] p) { + PriorityQueue minC = new PriorityQueue<>(new Comparator() { + @Override + public int compare(Program o1, Program o2) { + return o1.c - o2.c; + } + }); + + PriorityQueue maxP = new PriorityQueue<>(new Comparator() { + @Override + public int compare(Program o1, Program o2) { + return o2.p - o1.p; + } + }); + + for (int i = 0; i < c.length; i++) { + minC.add(new Program(c[i], p[i])); + } + + for (int i = 0; i < K; i++) { + while (!minC.isEmpty() && minC.peek().c >= W) { + maxP.add(minC.poll()); + } + if (maxP.isEmpty()) { + return W; + } + W += maxP.poll().p; + } + return W; + + } + + +} + +class 需要放置最大的灯泡数 { + + public int process(String str) { + char[] chars = str.toCharArray(); + int light = 0; + int i = 0; + while (i < chars.length) { + if (chars[i] == 'X') { + i++; + } else { + light++; + if (i + 1 == chars.length) { + break; + } + if (chars[i + 1] == 'X') { + i = i + 2; + } else { + i = i + 3; + } + } + + } + return light; + } +} \ No newline at end of file diff --git a/src/test/java/zuolaos/jichuban/Code18_并查集.java b/src/test/java/zuolaos/jichuban/Code18_并查集.java new file mode 100644 index 0000000..a4059b0 --- /dev/null +++ b/src/test/java/zuolaos/jichuban/Code18_并查集.java @@ -0,0 +1,269 @@ +package zuolaos.jichuban; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Stack; + +public class Code18_并查集 { + + +} + +class 并查集基本实现 { + private class Node { + V value; + + public Node(V value) { + this.value = value; + } + } + + private class UnionQueue { + public Map nodes = new HashMap<>(); + //指向父节点 + public Map parents = new HashMap<>(); + public Map nodeSize = new HashMap<>(); + + public UnionQueue(List values) { + for (V value : values) { + Node node = new Node<>(value); + nodes.put(value, node); + parents.put(node, node); + nodeSize.put(node, 1); + } + } + + public Node findFather(Node cur) { + Stack path = new Stack<>(); + while (cur != parents.get(cur)) { + path.add(cur); + cur = parents.get(cur); + } + while (!path.isEmpty()) { + parents.put(path.pop(), cur); + } + return cur; + } + + public void union(V a, V b) { + Node aHead = findFather(nodes.get(a)); + Node bHead = findFather(nodes.get(b)); + if (aHead != bHead) { + Integer aSize = nodeSize.get(aHead); + Integer bSize = nodeSize.get(bHead); + Node big = aSize > bSize ? aHead : bHead; + Node small = big == aHead ? bHead : aHead; + parents.put(small, big); + nodeSize.put(big, aSize + bSize); + nodeSize.remove(small); + } + } + + public boolean isSame(V a, V b) { + return findFather(nodes.get(a)) == findFather(nodes.get(b)); + } + + + } +} + + +//二维数组为1 表示认识,判断有多少个圈子 +class 朋友圈的个数_并查集法 { + public static int findCircleNum(int[][] M) { + int N = M.length; + UnionFind unionFind = new UnionFind(N); + for (int i = 0; i < N; i++) { + for (int j = i + 1; j < N; j++) { + if (M[i][j] == 1) { + unionFind.union(i, j); + } + } + } + return unionFind.getAllSet(); + } + + private static class UnionFind { + //i位置 指向的父节点位置 + int[] parent; + // + int[] size; + int[] help; + int allSet; + + public UnionFind(int N) { + parent = new int[N]; + size = new int[N]; + help = new int[N]; + for (int i = 0; i < N; i++) { + parent[i] = i; + size[i] = 1; + } + allSet = N; + } + + public int findFather(int i) { + int index = 0; + while (parent[i] != i) { + help[index++] = i; + i = parent[i]; + } + + while (index >= 0) { + parent[help[index--]] = i; + } + return i; + } + + public void union(int a, int b) { + int findA = findFather(a); + int findB = findFather(b); + if (findA == findB) { + if (size[findA] < size[findB]) { + parent[findA] = findB; + size[findB] += size[findA]; + } else { + parent[findB] = findA; + size[findA] += size[findB]; + } + allSet--; + } + } + + public int getAllSet() { + return allSet; + } + } +} + +class 动态岛问题并查集 { + + +} + +class 固定岛问题并查集 { + public int numIslands(char[][] board) { + int row = board.length; + int col = board[0].length; + //三个循环,判断是否认识 + UnionFind uf = new UnionFind(board); + for (int j = 1; j < col; j++) { + if (board[0][j - 1] == '1' && board[0][j] == '1') { + uf.union(0, j - 1, 0, j); + } + } + for (int i = 1; i < row; i++) { + if (board[i - 1][0] == '1' && board[i][0] == '1') { + uf.union(i - 1, 0, i, 0); + } + } + + for (int i = 1; i < row; i++) { + for (int j = 1; j < col; j++) { + if (board[i][j] == '1') { + if (board[i - 1][j] == '1') { + uf.union(i - 1, j, i, j); + } + if (board[i][j - 1] == '1') { + uf.union(i, j - 1, i, j); + } + } + } + } + return uf.sets; + } + + private class UnionFind { + private int[] parent; + private int[] size; + private int[] help; + int col; + int sets; + + public UnionFind(char[][] board) { + col = board[0].length; + int row = board.length; + int len = col * row; + sets = 0; + + parent = new int[len]; + size = new int[len]; + help = new int[len]; + for (int i = 0; i < row; i++) { + for (int j = 0; j < col; j++) { + if (board[i][j] == '1') { + int index = getIndex(i, j); + parent[index] = index; + size[index] = 1; + sets++; + } + } + } + } + + public int getIndex(int i, int j) { + return col * i + j; + } + + public void union(int r1, int c1, int r2, int c2) { + int index1 = getIndex(r1, c1); + int index2 = getIndex(r2, c2); + int find1 = findFather(index1); + int find2 = findFather(index2); + if (find1 != find2) { + if (size[find1] < size[find2]) { + parent[find1] = find2; + size[find2] += size[find1]; + } else { + parent[find2] = find1; + size[find1] += size[find2]; + } + sets--; + } + } + + public int findFather(int i) { + int hi = 0; + while (i == parent[i]) { + help[hi++] = i; + i = parent[i]; + } + while (hi >= 0) { + parent[help[hi--]] = i; + } + return i; + } + + } + +} + +//二维数组相邻的1连成一个岛 +class 固定岛问题感染法 { + public int numIslands(char[][] board) { + int M = board.length; + int N = board[0].length; + int ans = 0; + for (int i = 0; i < M; i++) { + for (int j = 0; j < N; j++) { + if (board[i][j] == '1') { + dfs(board, i, j); + } + } + } + return ans; + } + + private void dfs(char[][] board, int i, int j) { + if (i < 0 || i >= board.length || j < 0 || j >= board[0].length || board[i][j] != '1') { + return; + } + board[i][j] = 0; + dfs(board, i - 1, j); + dfs(board, i + 1, j); + dfs(board, i, j - 1); + dfs(board, i, j + 1); + } + +} \ No newline at end of file