From 34545e8ff205b6229bd772505aa4bcef8f0a6cc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B7=A6=E7=A8=8B=E4=BA=91?= Date: Sat, 26 Dec 2020 23:52:23 +0800 Subject: [PATCH 1/3] modify code on class --- src/class10/Code01_BFS.java | 8 ++-- src/class10/Code02_DFS.java | 3 ++ src/class10/Code03_TopologicalOrderDFS2.java | 6 +++ src/class10/Code03_TopologySort.java | 2 + src/class10/Code04_Kruskal.java | 1 + src/class10/Code05_Prim.java | 4 ++ src/class10/Code06_Dijkstra.java | 4 +- src/class10/GraphGenerator.java | 16 +++++--- src/class10/Node.java | 2 +- src/class11/Code06_ConvertToLetterString.java | 37 ++----------------- 10 files changed, 38 insertions(+), 45 deletions(-) diff --git a/src/class10/Code01_BFS.java b/src/class10/Code01_BFS.java index c219524..e6d7fc2 100644 --- a/src/class10/Code01_BFS.java +++ b/src/class10/Code01_BFS.java @@ -7,14 +7,14 @@ import java.util.Queue; public class Code01_BFS { // 从node出发,进行宽度优先遍历 - public static void bfs(Node node) { - if (node == null) { + public static void bfs(Node start) { + if (start == null) { return; } Queue queue = new LinkedList<>(); HashSet set = new HashSet<>(); - queue.add(node); - set.add(node); + queue.add(start); + set.add(start); while (!queue.isEmpty()) { Node cur = queue.poll(); System.out.println(cur.value); diff --git a/src/class10/Code02_DFS.java b/src/class10/Code02_DFS.java index 6ecc3cf..4c73d6b 100644 --- a/src/class10/Code02_DFS.java +++ b/src/class10/Code02_DFS.java @@ -27,5 +27,8 @@ public class Code02_DFS { } } } + + + } diff --git a/src/class10/Code03_TopologicalOrderDFS2.java b/src/class10/Code03_TopologicalOrderDFS2.java index 7cf5f79..c74c1ab 100644 --- a/src/class10/Code03_TopologicalOrderDFS2.java +++ b/src/class10/Code03_TopologicalOrderDFS2.java @@ -54,10 +54,16 @@ public class Code03_TopologicalOrderDFS2 { return ans; } + // 当前来到cur点,请返回cur点所到之处,所有的点次! + // 返回(cur,点次) + // 缓存!!!!!order + // key : 某一个点的点次,之前算过了! + // value : 点次是多少 public static Record f(DirectedGraphNode cur, HashMap order) { if (order.containsKey(cur)) { return order.get(cur); } + // cur的点次之前没算过! long nodes = 0; for (DirectedGraphNode next : cur.neighbors) { nodes += f(next, order).nodes; diff --git a/src/class10/Code03_TopologySort.java b/src/class10/Code03_TopologySort.java index 2c79e2f..431c67d 100644 --- a/src/class10/Code03_TopologySort.java +++ b/src/class10/Code03_TopologySort.java @@ -10,7 +10,9 @@ public class Code03_TopologySort { // directed graph and no loop public static List sortedTopology(Graph graph) { + // key 某个节点 value 剩余的入度 HashMap inMap = new HashMap<>(); + // 只有剩余入度为0的点,才进入这个队列 Queue zeroInQueue = new LinkedList<>(); for (Node node : graph.nodes.values()) { inMap.put(node, node.in); diff --git a/src/class10/Code04_Kruskal.java b/src/class10/Code04_Kruskal.java index e95a1fc..eb1342f 100644 --- a/src/class10/Code04_Kruskal.java +++ b/src/class10/Code04_Kruskal.java @@ -83,6 +83,7 @@ public class Code04_Kruskal { public static Set kruskalMST(Graph graph) { UnionFind unionFind = new UnionFind(); unionFind.makeSets(graph.nodes.values()); + // 从小的边到大的边,依次弹出,小根堆! PriorityQueue priorityQueue = new PriorityQueue<>(new EdgeComparator()); for (Edge edge : graph.edges) { // M 条边 priorityQueue.add(edge); // O(logM) diff --git a/src/class10/Code05_Prim.java b/src/class10/Code05_Prim.java index 9564d3b..a937115 100644 --- a/src/class10/Code05_Prim.java +++ b/src/class10/Code05_Prim.java @@ -23,7 +23,11 @@ public class Code05_Prim { // 哪些点被解锁出来了 HashSet nodeSet = new HashSet<>(); + + + Set result = new HashSet<>(); // 依次挑选的的边在result里 + for (Node node : graph.nodes.values()) { // 随便挑了一个点 // node 是开始点 if (!nodeSet.contains(node)) { diff --git a/src/class10/Code06_Dijkstra.java b/src/class10/Code06_Dijkstra.java index b20d01d..713cd7d 100644 --- a/src/class10/Code06_Dijkstra.java +++ b/src/class10/Code06_Dijkstra.java @@ -10,15 +10,17 @@ public class Code06_Dijkstra { public static HashMap dijkstra1(Node from) { HashMap distanceMap = new HashMap<>(); distanceMap.put(from, 0); + // 打过对号的点 HashSet selectedNodes = new HashSet<>(); Node minNode = getMinDistanceAndUnselectedNode(distanceMap, selectedNodes); while (minNode != null) { + // 原始点 -> minNode(跳转点) 最小距离distance int distance = distanceMap.get(minNode); for (Edge edge : minNode.edges) { Node toNode = edge.to; if (!distanceMap.containsKey(toNode)) { distanceMap.put(toNode, distance + edge.weight); - } else { + } else { // toNode distanceMap.put(edge.to, Math.min(distanceMap.get(toNode), distance + edge.weight)); } } diff --git a/src/class10/GraphGenerator.java b/src/class10/GraphGenerator.java index 1180e20..73287f6 100644 --- a/src/class10/GraphGenerator.java +++ b/src/class10/GraphGenerator.java @@ -5,13 +5,17 @@ public class GraphGenerator { // matrix 所有的边 // N*3 的矩阵 // [weight, from节点上面的值,to节点上面的值] - public static Graph createGraph(Integer[][] matrix) { + // + // [ 5 , 0 , 7] + // [ 3 , 0, 1] + // + public static Graph createGraph(int[][] matrix) { Graph graph = new Graph(); - for (int i = 0; i < matrix.length; i++) { - // matrix[0][0], matrix[0][1] matrix[0][2] - Integer weight = matrix[i][0]; - Integer from = matrix[i][1]; - Integer to = matrix[i][2]; + for (int i = 0; i < matrix.length; i++) { + // 拿到每一条边, matrix[i] + int weight = matrix[i][0]; + int from = matrix[i][1]; + int to = matrix[i][2]; if (!graph.nodes.containsKey(from)) { graph.nodes.put(from, new Node(from)); } diff --git a/src/class10/Node.java b/src/class10/Node.java index d022d12..256ab4c 100644 --- a/src/class10/Node.java +++ b/src/class10/Node.java @@ -2,7 +2,7 @@ package class10; import java.util.ArrayList; -// 点结构的描述 A 0 +// 点结构的描述 public class Node { public int value; public int in; diff --git a/src/class11/Code06_ConvertToLetterString.java b/src/class11/Code06_ConvertToLetterString.java index aa1c7ec..1458cf4 100644 --- a/src/class11/Code06_ConvertToLetterString.java +++ b/src/class11/Code06_ConvertToLetterString.java @@ -34,38 +34,9 @@ public class Code06_ConvertToLetterString { return res; } return process(str, i + 1); - } - - public static int dpWays2(String s) { - if (s == null || s.length() == 0) { - return 0; - } - char[] str = s.toCharArray(); - int N = str.length; - int[] dp = new int[N+1]; - dp[N] = 1; - for(int i = N-1; i >= 0; i--) { - if (str[i] == '0') { - dp[i] = 0; - } - if (str[i] == '1') { - dp[i] = dp[i + 1]; - if (i + 1 < str.length) { - dp[i] += dp[i + 2]; - } - } - if (str[i] == '2') { - dp[i] = dp[i + 1]; - if (i + 1 < str.length && (str[i + 1] >= '0' && str[i + 1] <= '6')) { - dp[i] += dp[i + 2]; // (i和i+1)作为单独的部分,后续有多少种方法 - } - } - } - return dp[0]; - } - + } - public static int dpWays(String s) { + public static int dp(String s) { if (s == null || s.length() == 0) { return 0; } @@ -94,8 +65,8 @@ public class Code06_ConvertToLetterString { } public static void main(String[] args) { - System.out.println(number("11111")); - System.out.println(dpWays2("11111")); + System.out.println(number("2132082")); + System.out.println(dp("2132082")); } } From c0d73f8502d82e1e43396796da2c5bcc2adea9a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B7=A6=E7=A8=8B=E4=BA=91?= Date: Mon, 28 Dec 2020 12:44:20 +0800 Subject: [PATCH 2/3] modify code on class --- src/{class10 => class10_16}/Code01_BFS.java | 2 +- src/{class10 => class10_16}/Code02_DFS.java | 2 +- .../Code03_TopologicalOrderBFS.java | 2 +- .../Code03_TopologicalOrderDFS1.java | 2 +- .../Code03_TopologicalOrderDFS2.java | 2 +- .../Code03_TopologySort.java | 2 +- .../Code04_Kruskal.java | 2 +- src/{class10 => class10_16}/Code05_Prim.java | 2 +- .../Code06_Dijkstra.java | 2 +- src/{class10 => class10_16}/Edge.java | 2 +- src/{class10 => class10_16}/Graph.java | 2 +- .../GraphGenerator.java | 2 +- src/{class10 => class10_16}/Node.java | 2 +- src/class10_17/Code01_Dijkstra.java | 160 ++++++++++++++++++ src/class10_17/Edge.java | 14 ++ src/class10_17/Graph.java | 14 ++ src/class10_17/Node.java | 20 +++ src/{class11 => class11_17}/Code01_Hanoi.java | 2 +- .../Code02_PrintAllSubsquences.java | 2 +- .../Code03_PrintAllPermutations.java | 2 +- .../Code04_ReverseStackUsingRecursive.java | 2 +- .../Code06_ConvertToLetterString.java | 2 +- .../Code07_Knapsack.java | 2 +- .../Code08_CardsInLine.java | 2 +- .../Code09_NQueens.java | 2 +- 25 files changed, 229 insertions(+), 21 deletions(-) rename src/{class10 => class10_16}/Code01_BFS.java (96%) rename src/{class10 => class10_16}/Code02_DFS.java (96%) rename src/{class10 => class10_16}/Code03_TopologicalOrderBFS.java (98%) rename src/{class10 => class10_16}/Code03_TopologicalOrderDFS1.java (98%) rename src/{class10 => class10_16}/Code03_TopologicalOrderDFS2.java (98%) rename src/{class10 => class10_16}/Code03_TopologySort.java (97%) rename src/{class10 => class10_16}/Code04_Kruskal.java (99%) rename src/{class10 => class10_16}/Code05_Prim.java (99%) rename src/{class10 => class10_16}/Code06_Dijkstra.java (99%) rename src/{class10 => class10_16}/Edge.java (90%) rename src/{class10 => class10_16}/Graph.java (91%) rename src/{class10 => class10_16}/GraphGenerator.java (97%) rename src/{class10 => class10_16}/Node.java (94%) create mode 100644 src/class10_17/Code01_Dijkstra.java create mode 100644 src/class10_17/Edge.java create mode 100644 src/class10_17/Graph.java create mode 100644 src/class10_17/Node.java rename src/{class11 => class11_17}/Code01_Hanoi.java (99%) rename src/{class11 => class11_17}/Code02_PrintAllSubsquences.java (98%) rename src/{class11 => class11_17}/Code03_PrintAllPermutations.java (99%) rename src/{class11 => class11_17}/Code04_ReverseStackUsingRecursive.java (97%) rename src/{class11 => class11_17}/Code06_ConvertToLetterString.java (94%) rename src/{class11 => class11_17}/Code07_Knapsack.java (99%) rename src/{class11 => class11_17}/Code08_CardsInLine.java (98%) rename src/{class11 => class11_17}/Code09_NQueens.java (99%) diff --git a/src/class10/Code01_BFS.java b/src/class10_16/Code01_BFS.java similarity index 96% rename from src/class10/Code01_BFS.java rename to src/class10_16/Code01_BFS.java index e6d7fc2..3a6ac94 100644 --- a/src/class10/Code01_BFS.java +++ b/src/class10_16/Code01_BFS.java @@ -1,4 +1,4 @@ -package class10; +package class10_16; import java.util.HashSet; import java.util.LinkedList; diff --git a/src/class10/Code02_DFS.java b/src/class10_16/Code02_DFS.java similarity index 96% rename from src/class10/Code02_DFS.java rename to src/class10_16/Code02_DFS.java index 4c73d6b..4e29e8f 100644 --- a/src/class10/Code02_DFS.java +++ b/src/class10_16/Code02_DFS.java @@ -1,4 +1,4 @@ -package class10; +package class10_16; import java.util.HashSet; import java.util.Stack; diff --git a/src/class10/Code03_TopologicalOrderBFS.java b/src/class10_16/Code03_TopologicalOrderBFS.java similarity index 98% rename from src/class10/Code03_TopologicalOrderBFS.java rename to src/class10_16/Code03_TopologicalOrderBFS.java index 07f61b1..f672e78 100644 --- a/src/class10/Code03_TopologicalOrderBFS.java +++ b/src/class10_16/Code03_TopologicalOrderBFS.java @@ -1,4 +1,4 @@ -package class10; +package class10_16; import java.util.ArrayList; import java.util.HashMap; diff --git a/src/class10/Code03_TopologicalOrderDFS1.java b/src/class10_16/Code03_TopologicalOrderDFS1.java similarity index 98% rename from src/class10/Code03_TopologicalOrderDFS1.java rename to src/class10_16/Code03_TopologicalOrderDFS1.java index 9514606..35c74f0 100644 --- a/src/class10/Code03_TopologicalOrderDFS1.java +++ b/src/class10_16/Code03_TopologicalOrderDFS1.java @@ -1,4 +1,4 @@ -package class10; +package class10_16; import java.util.ArrayList; import java.util.Comparator; diff --git a/src/class10/Code03_TopologicalOrderDFS2.java b/src/class10_16/Code03_TopologicalOrderDFS2.java similarity index 98% rename from src/class10/Code03_TopologicalOrderDFS2.java rename to src/class10_16/Code03_TopologicalOrderDFS2.java index c74c1ab..bbecfa5 100644 --- a/src/class10/Code03_TopologicalOrderDFS2.java +++ b/src/class10_16/Code03_TopologicalOrderDFS2.java @@ -1,4 +1,4 @@ -package class10; +package class10_16; import java.util.ArrayList; import java.util.Comparator; diff --git a/src/class10/Code03_TopologySort.java b/src/class10_16/Code03_TopologySort.java similarity index 97% rename from src/class10/Code03_TopologySort.java rename to src/class10_16/Code03_TopologySort.java index 431c67d..aa25007 100644 --- a/src/class10/Code03_TopologySort.java +++ b/src/class10_16/Code03_TopologySort.java @@ -1,4 +1,4 @@ -package class10; +package class10_16; import java.util.ArrayList; import java.util.HashMap; diff --git a/src/class10/Code04_Kruskal.java b/src/class10_16/Code04_Kruskal.java similarity index 99% rename from src/class10/Code04_Kruskal.java rename to src/class10_16/Code04_Kruskal.java index eb1342f..03ef6c4 100644 --- a/src/class10/Code04_Kruskal.java +++ b/src/class10_16/Code04_Kruskal.java @@ -1,4 +1,4 @@ -package class10; +package class10_16; import java.util.Collection; import java.util.Comparator; diff --git a/src/class10/Code05_Prim.java b/src/class10_16/Code05_Prim.java similarity index 99% rename from src/class10/Code05_Prim.java rename to src/class10_16/Code05_Prim.java index a937115..c8ace77 100644 --- a/src/class10/Code05_Prim.java +++ b/src/class10_16/Code05_Prim.java @@ -1,4 +1,4 @@ -package class10; +package class10_16; import java.util.Comparator; import java.util.HashSet; diff --git a/src/class10/Code06_Dijkstra.java b/src/class10_16/Code06_Dijkstra.java similarity index 99% rename from src/class10/Code06_Dijkstra.java rename to src/class10_16/Code06_Dijkstra.java index 713cd7d..a50528a 100644 --- a/src/class10/Code06_Dijkstra.java +++ b/src/class10_16/Code06_Dijkstra.java @@ -1,4 +1,4 @@ -package class10; +package class10_16; import java.util.HashMap; import java.util.HashSet; diff --git a/src/class10/Edge.java b/src/class10_16/Edge.java similarity index 90% rename from src/class10/Edge.java rename to src/class10_16/Edge.java index 8786552..3b8e939 100644 --- a/src/class10/Edge.java +++ b/src/class10_16/Edge.java @@ -1,4 +1,4 @@ -package class10; +package class10_16; public class Edge { public int weight; diff --git a/src/class10/Graph.java b/src/class10_16/Graph.java similarity index 91% rename from src/class10/Graph.java rename to src/class10_16/Graph.java index b70e007..d7556e8 100644 --- a/src/class10/Graph.java +++ b/src/class10_16/Graph.java @@ -1,4 +1,4 @@ -package class10; +package class10_16; import java.util.HashMap; import java.util.HashSet; diff --git a/src/class10/GraphGenerator.java b/src/class10_16/GraphGenerator.java similarity index 97% rename from src/class10/GraphGenerator.java rename to src/class10_16/GraphGenerator.java index 73287f6..4c07bc5 100644 --- a/src/class10/GraphGenerator.java +++ b/src/class10_16/GraphGenerator.java @@ -1,4 +1,4 @@ -package class10; +package class10_16; public class GraphGenerator { diff --git a/src/class10/Node.java b/src/class10_16/Node.java similarity index 94% rename from src/class10/Node.java rename to src/class10_16/Node.java index 256ab4c..1a57f35 100644 --- a/src/class10/Node.java +++ b/src/class10_16/Node.java @@ -1,4 +1,4 @@ -package class10; +package class10_16; import java.util.ArrayList; diff --git a/src/class10_17/Code01_Dijkstra.java b/src/class10_17/Code01_Dijkstra.java new file mode 100644 index 0000000..8e38bb4 --- /dev/null +++ b/src/class10_17/Code01_Dijkstra.java @@ -0,0 +1,160 @@ +package class10_17; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map.Entry; + +// no negative weight +public class Code01_Dijkstra { + + public static HashMap dijkstra1(Node from) { + HashMap distanceMap = new HashMap<>(); + distanceMap.put(from, 0); + // 打过对号的点 + HashSet selectedNodes = new HashSet<>(); + Node minNode = getMinDistanceAndUnselectedNode(distanceMap, selectedNodes); + while (minNode != null) { + // 原始点 -> minNode(跳转点) 最小距离distance + int distance = distanceMap.get(minNode); + for (Edge edge : minNode.edges) { + Node toNode = edge.to; + if (!distanceMap.containsKey(toNode)) { + distanceMap.put(toNode, distance + edge.weight); + } else { // toNode + distanceMap.put(edge.to, Math.min(distanceMap.get(toNode), distance + edge.weight)); + } + } + selectedNodes.add(minNode); + minNode = getMinDistanceAndUnselectedNode(distanceMap, selectedNodes); + } + return distanceMap; + } + + public static Node getMinDistanceAndUnselectedNode(HashMap distanceMap, HashSet touchedNodes) { + Node minNode = null; + int minDistance = Integer.MAX_VALUE; + for (Entry entry : distanceMap.entrySet()) { + Node node = entry.getKey(); + int distance = entry.getValue(); + if (!touchedNodes.contains(node) && distance < minDistance) { + minNode = node; + minDistance = distance; + } + } + return minNode; + } + + public static class NodeRecord { + public Node node; + public int distance; + + public NodeRecord(Node node, int distance) { + this.node = node; + this.distance = distance; + } + } + + public static class NodeHeap { + private Node[] nodes; // 实际的堆结构 + // key 某一个node, value 上面堆中的位置 + private HashMap heapIndexMap; + // key 某一个节点, value 从源节点出发到该节点的目前最小距离 + private HashMap distanceMap; + private int size; // 堆上有多少个点 + + public NodeHeap(int size) { + nodes = new Node[size]; + heapIndexMap = new HashMap<>(); + distanceMap = new HashMap<>(); + size = 0; + } + + public boolean isEmpty() { + return size == 0; + } + + // 有一个点叫node,现在发现了一个从源节点出发到达node的距离为distance + // 判断要不要更新,如果需要的话,就更新 + public void addOrUpdateOrIgnore(Node node, int distance) { + if (inHeap(node)) { + distanceMap.put(node, Math.min(distanceMap.get(node), distance)); + insertHeapify(node, heapIndexMap.get(node)); + } + if (!isEntered(node)) { + nodes[size] = node; + heapIndexMap.put(node, size); + distanceMap.put(node, distance); + insertHeapify(node, size++); + } + } + + public NodeRecord pop() { + NodeRecord nodeRecord = new NodeRecord(nodes[0], distanceMap.get(nodes[0])); + swap(0, size - 1); + heapIndexMap.put(nodes[size - 1], -1); + distanceMap.remove(nodes[size - 1]); + // free C++同学还要把原本堆顶节点析构,对java同学不必 + nodes[size - 1] = null; + heapify(0, --size); + return nodeRecord; + } + + private void insertHeapify(Node node, int index) { + while (distanceMap.get(nodes[index]) < distanceMap.get(nodes[(index - 1) / 2])) { + swap(index, (index - 1) / 2); + index = (index - 1) / 2; + } + } + + private void heapify(int index, int size) { + int left = index * 2 + 1; + while (left < size) { + int smallest = left + 1 < size && distanceMap.get(nodes[left + 1]) < distanceMap.get(nodes[left]) + ? left + 1 + : left; + smallest = distanceMap.get(nodes[smallest]) < distanceMap.get(nodes[index]) ? smallest : index; + if (smallest == index) { + break; + } + swap(smallest, index); + index = smallest; + left = index * 2 + 1; + } + } + + private boolean isEntered(Node node) { + return heapIndexMap.containsKey(node); + } + + private boolean inHeap(Node node) { + return isEntered(node) && heapIndexMap.get(node) != -1; + } + + private void swap(int index1, int index2) { + heapIndexMap.put(nodes[index1], index2); + heapIndexMap.put(nodes[index2], index1); + Node tmp = nodes[index1]; + nodes[index1] = nodes[index2]; + nodes[index2] = tmp; + } + } + + // 改进后的dijkstra算法 + // 从head出发,所有head能到达的节点,生成到达每个节点的最小路径记录并返回 + public static HashMap dijkstra2(Node head, int size) { + NodeHeap nodeHeap = new NodeHeap(size); + nodeHeap.addOrUpdateOrIgnore(head, 0); + HashMap result = new HashMap<>(); + while (!nodeHeap.isEmpty()) { + NodeRecord record = nodeHeap.pop(); + Node cur = record.node; + int distance = record.distance; + for (Edge edge : cur.edges) { + nodeHeap.addOrUpdateOrIgnore(edge.to, edge.weight + distance); + } + result.put(cur, distance); + } + return result; + } + +} diff --git a/src/class10_17/Edge.java b/src/class10_17/Edge.java new file mode 100644 index 0000000..b4389ea --- /dev/null +++ b/src/class10_17/Edge.java @@ -0,0 +1,14 @@ +package class10_17; + +public class Edge { + public int weight; + public Node from; + public Node to; + + public Edge(int weight, Node from, Node to) { + this.weight = weight; + this.from = from; + this.to = to; + } + +} diff --git a/src/class10_17/Graph.java b/src/class10_17/Graph.java new file mode 100644 index 0000000..3901b78 --- /dev/null +++ b/src/class10_17/Graph.java @@ -0,0 +1,14 @@ +package class10_17; + +import java.util.HashMap; +import java.util.HashSet; + +public class Graph { + public HashMap nodes; + public HashSet edges; + + public Graph() { + nodes = new HashMap<>(); + edges = new HashSet<>(); + } +} diff --git a/src/class10_17/Node.java b/src/class10_17/Node.java new file mode 100644 index 0000000..79a92d3 --- /dev/null +++ b/src/class10_17/Node.java @@ -0,0 +1,20 @@ +package class10_17; + +import java.util.ArrayList; + +// 点结构的描述 +public class Node { + public int value; + public int in; + public int out; + public ArrayList nexts; + public ArrayList edges; + + public Node(int value) { + this.value = value; + in = 0; + out = 0; + nexts = new ArrayList<>(); + edges = new ArrayList<>(); + } +} diff --git a/src/class11/Code01_Hanoi.java b/src/class11_17/Code01_Hanoi.java similarity index 99% rename from src/class11/Code01_Hanoi.java rename to src/class11_17/Code01_Hanoi.java index 1872653..4b3966c 100644 --- a/src/class11/Code01_Hanoi.java +++ b/src/class11_17/Code01_Hanoi.java @@ -1,4 +1,4 @@ -package class11; +package class11_17; import java.util.Stack; diff --git a/src/class11/Code02_PrintAllSubsquences.java b/src/class11_17/Code02_PrintAllSubsquences.java similarity index 98% rename from src/class11/Code02_PrintAllSubsquences.java rename to src/class11_17/Code02_PrintAllSubsquences.java index 28509c3..505e878 100644 --- a/src/class11/Code02_PrintAllSubsquences.java +++ b/src/class11_17/Code02_PrintAllSubsquences.java @@ -1,4 +1,4 @@ -package class11; +package class11_17; import java.util.ArrayList; import java.util.HashSet; diff --git a/src/class11/Code03_PrintAllPermutations.java b/src/class11_17/Code03_PrintAllPermutations.java similarity index 99% rename from src/class11/Code03_PrintAllPermutations.java rename to src/class11_17/Code03_PrintAllPermutations.java index 349eedd..332acf4 100644 --- a/src/class11/Code03_PrintAllPermutations.java +++ b/src/class11_17/Code03_PrintAllPermutations.java @@ -1,4 +1,4 @@ -package class11; +package class11_17; import java.util.ArrayList; import java.util.List; diff --git a/src/class11/Code04_ReverseStackUsingRecursive.java b/src/class11_17/Code04_ReverseStackUsingRecursive.java similarity index 97% rename from src/class11/Code04_ReverseStackUsingRecursive.java rename to src/class11_17/Code04_ReverseStackUsingRecursive.java index 8e9134c..4653b9b 100644 --- a/src/class11/Code04_ReverseStackUsingRecursive.java +++ b/src/class11_17/Code04_ReverseStackUsingRecursive.java @@ -1,4 +1,4 @@ -package class11; +package class11_17; import java.util.Stack; diff --git a/src/class11/Code06_ConvertToLetterString.java b/src/class11_17/Code06_ConvertToLetterString.java similarity index 94% rename from src/class11/Code06_ConvertToLetterString.java rename to src/class11_17/Code06_ConvertToLetterString.java index 1458cf4..0b66871 100644 --- a/src/class11/Code06_ConvertToLetterString.java +++ b/src/class11_17/Code06_ConvertToLetterString.java @@ -1,4 +1,4 @@ -package class11; +package class11_17; public class Code06_ConvertToLetterString { diff --git a/src/class11/Code07_Knapsack.java b/src/class11_17/Code07_Knapsack.java similarity index 99% rename from src/class11/Code07_Knapsack.java rename to src/class11_17/Code07_Knapsack.java index 76e0616..fcfa7c7 100644 --- a/src/class11/Code07_Knapsack.java +++ b/src/class11_17/Code07_Knapsack.java @@ -1,4 +1,4 @@ -package class11; +package class11_17; public class Code07_Knapsack { diff --git a/src/class11/Code08_CardsInLine.java b/src/class11_17/Code08_CardsInLine.java similarity index 98% rename from src/class11/Code08_CardsInLine.java rename to src/class11_17/Code08_CardsInLine.java index b15a723..ddcb9da 100644 --- a/src/class11/Code08_CardsInLine.java +++ b/src/class11_17/Code08_CardsInLine.java @@ -1,4 +1,4 @@ -package class11; +package class11_17; public class Code08_CardsInLine { diff --git a/src/class11/Code09_NQueens.java b/src/class11_17/Code09_NQueens.java similarity index 99% rename from src/class11/Code09_NQueens.java rename to src/class11_17/Code09_NQueens.java index 8868d2c..05da2b6 100644 --- a/src/class11/Code09_NQueens.java +++ b/src/class11_17/Code09_NQueens.java @@ -1,4 +1,4 @@ -package class11; +package class11_17; public class Code09_NQueens { From 6041ac97e141b896c435c4181b0ddb5bf6c411b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B7=A6=E7=A8=8B=E4=BA=91?= Date: Mon, 28 Dec 2020 12:47:30 +0800 Subject: [PATCH 3/3] add new problem --- src/class12/Code10_SplitSumClosed.java | 106 +++++++++++++++ .../Code11_SplitSumClosedSizeHalf.java | 122 ++++++++++++++++++ 2 files changed, 228 insertions(+) create mode 100644 src/class12/Code10_SplitSumClosed.java create mode 100644 src/class12/Code11_SplitSumClosedSizeHalf.java diff --git a/src/class12/Code10_SplitSumClosed.java b/src/class12/Code10_SplitSumClosed.java new file mode 100644 index 0000000..d12b567 --- /dev/null +++ b/src/class12/Code10_SplitSumClosed.java @@ -0,0 +1,106 @@ +package class12; + +import java.util.TreeSet; + +/* + * 给定一个整型数组arr,请把arr中所有的数分成两个集合,尽量让两个集合的累加和接近 + * 返回最接近的情况下,较小集合的累加和(较大集合的累加和一定是所有数累加和减去较小集合的累加和) + * 为了方便起见,假设arr中没有负数,其实也可以有 + * 但是处理起来会比较麻烦,而且有没有负数都不影响算法流程的理解 + * */ +public class Code10_SplitSumClosed { + + public static int right(int[] arr) { + if (arr == null || arr.length < 2) { + return 0; + } + int sum = 0; + for (int num : arr) { + sum += num; + } + TreeSet ans = new TreeSet<>(); + process(arr, 0, 0, 0, ans, sum >> 1); + return ans.last(); + } + + public static void process(int[] arr, int i, int sum, int picks, TreeSet ans, int limit) { + if (i == arr.length) { + if (sum <= limit) { + ans.add(sum); + } + } else { + process(arr, i + 1, sum, picks, ans, limit); + process(arr, i + 1, sum + arr[i], picks + 1, ans, limit); + } + } + + public static int dp(int[] arr) { + if (arr == null || arr.length < 2) { + return 0; + } + int sum = 0; + for (int num : arr) { + sum += num; + } + sum >>= 1; + int N = arr.length; + boolean[][] dp = new boolean[N][sum + 1]; + for (int i = 0; i < N; i++) { + dp[i][0] = true; + } + if (arr[0] <= sum) { + dp[0][arr[0]] = true; + } + for (int i = 1; i < N; i++) { + for (int j = 1; j <= sum; j++) { + dp[i][j] = dp[i - 1][j]; + if (j - arr[i] >= 0) { + dp[i][j] |= dp[i - 1][j - arr[i]]; + } + } + } + for (int j = sum; j >= 1; j--) { + if (dp[N - 1][j]) { + return j; + } + } + return 0; + } + + public static int[] randomArray(int len, int value) { + int[] arr = new int[len]; + for (int i = 0; i < arr.length; i++) { + arr[i] = (int) (Math.random() * value); + } + return arr; + } + + public static void printArray(int[] arr) { + for (int num : arr) { + System.out.print(num + " "); + } + System.out.println(); + } + + public static void main(String[] args) { + int maxLen = 20; + int maxValue = 50; + int testTime = 10000; + System.out.println("测试开始"); + for (int i = 0; i < testTime; i++) { + int len = (int) (Math.random() * maxLen); + int[] arr = randomArray(len, maxValue); + int ans1 = right(arr); + int ans2 = dp(arr); + if (ans1 != ans2) { + printArray(arr); + System.out.println(ans1); + System.out.println(ans2); + System.out.println("Oops!"); + break; + } + } + System.out.println("测试结束"); + } + +} diff --git a/src/class12/Code11_SplitSumClosedSizeHalf.java b/src/class12/Code11_SplitSumClosedSizeHalf.java new file mode 100644 index 0000000..bf2c28b --- /dev/null +++ b/src/class12/Code11_SplitSumClosedSizeHalf.java @@ -0,0 +1,122 @@ +package class12; + +import java.util.TreeSet; + +/* + * 给定一个整型数组arr,请把arr中所有的数分成两个集合 + * 如果arr长度为偶数,两个集合包含数的个数要一样多 + * 如果arr长度为奇数,两个集合包含数的个数必须只差一个 + * 请尽量让两个集合的累加和接近 + * 返回最接近的情况下,较小集合的累加和(较大集合的累加和一定是所有数累加和减去较小集合的累加和) + * 为了方便起见,假设arr中没有负数,其实也可以有 + * 但是处理起来会比较麻烦,而且有没有负数都不影响算法流程的理解 + * */ +public class Code11_SplitSumClosedSizeHalf { + + public static int right(int[] arr) { + if (arr == null || arr.length < 2) { + return 0; + } + int sum = 0; + for (int num : arr) { + sum += num; + } + TreeSet ans = new TreeSet<>(); + process(arr, 0, 0, 0, ans, sum >> 1); + return ans.last(); + } + + public static void process(int[] arr, int i, int sum, int picks, TreeSet ans, int limit) { + if (i == arr.length) { + if ((arr.length & 1) == 0) { + if (picks == (arr.length >> 1) && sum <= limit) { + ans.add(sum); + } + } else { + if ((picks == (arr.length >> 1) || picks == (arr.length >> 1) + 1) && sum <= limit) { + ans.add(sum); + } + } + } else { + process(arr, i + 1, sum, picks, ans, limit); + process(arr, i + 1, sum + arr[i], picks + 1, ans, limit); + } + } + + public static int dp(int[] arr) { + if (arr == null || arr.length < 2) { + return 0; + } + int sum = 0; + for (int num : arr) { + sum += num; + } + sum >>= 1; + int N = arr.length; + int M = (arr.length + 1) >> 1; + int[][][] dp = new int[N][M + 1][sum + 1]; + for (int i = 0; i < N; i++) { + for (int j = 0; j <= M; j++) { + for (int k = 0; k <= sum; k++) { + dp[i][j][k] = Integer.MIN_VALUE; + } + } + } + for (int i = 0; i < N; i++) { + for (int k = 0; k <= sum; k++) { + dp[i][0][k] = 0; + } + } + for (int k = 0; k <= sum; k++) { + dp[0][1][k] = arr[0] <= k ? arr[0] : Integer.MIN_VALUE; + } + for (int i = 1; i < N; i++) { + for (int j = 1; j <= Math.min(i + 1, M); j++) { + for (int k = 0; k <= sum; k++) { + dp[i][j][k] = dp[i - 1][j][k]; + if (k - arr[i] >= 0) { + dp[i][j][k] = Math.max(dp[i][j][k], dp[i - 1][j - 1][k - arr[i]] + arr[i]); + } + } + } + } + return Math.max(dp[N - 1][M][sum], dp[N - 1][N - M][sum]); + } + + public static int[] randomArray(int len, int value) { + int[] arr = new int[len]; + for (int i = 0; i < arr.length; i++) { + arr[i] = (int) (Math.random() * value); + } + return arr; + } + + public static void printArray(int[] arr) { + for (int num : arr) { + System.out.print(num + " "); + } + System.out.println(); + } + + public static void main(String[] args) { + int maxLen = 20; + int maxValue = 50; + int testTime = 10000; + System.out.println("测试开始"); + for (int i = 0; i < testTime; i++) { + int len = (int) (Math.random() * maxLen); + int[] arr = randomArray(len, maxValue); + int ans1 = right(arr); + int ans2 = dp(arr); + if (ans1 != ans2) { + printArray(arr); + System.out.println(ans1); + System.out.println(ans2); + System.out.println("Oops!"); + break; + } + } + System.out.println("测试结束"); + } + +} \ No newline at end of file