Merge pull request #13 from algorithmzuo/master

update zuo
pull/3/head
ThankyouEverybody 5 years ago committed by GitHub
commit 2b90643e6f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,4 +1,4 @@
package class10; package class10_16;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
@ -7,14 +7,14 @@ import java.util.Queue;
public class Code01_BFS { public class Code01_BFS {
// 从node出发进行宽度优先遍历 // 从node出发进行宽度优先遍历
public static void bfs(Node node) { public static void bfs(Node start) {
if (node == null) { if (start == null) {
return; return;
} }
Queue<Node> queue = new LinkedList<>(); Queue<Node> queue = new LinkedList<>();
HashSet<Node> set = new HashSet<>(); HashSet<Node> set = new HashSet<>();
queue.add(node); queue.add(start);
set.add(node); set.add(start);
while (!queue.isEmpty()) { while (!queue.isEmpty()) {
Node cur = queue.poll(); Node cur = queue.poll();
System.out.println(cur.value); System.out.println(cur.value);

@ -1,4 +1,4 @@
package class10; package class10_16;
import java.util.HashSet; import java.util.HashSet;
import java.util.Stack; import java.util.Stack;
@ -27,5 +27,8 @@ public class Code02_DFS {
} }
} }
} }
} }

@ -1,4 +1,4 @@
package class10; package class10_16;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;

@ -1,4 +1,4 @@
package class10; package class10_16;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator; import java.util.Comparator;

@ -1,4 +1,4 @@
package class10; package class10_16;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator; import java.util.Comparator;
@ -54,10 +54,16 @@ public class Code03_TopologicalOrderDFS2 {
return ans; return ans;
} }
// 当前来到cur点请返回cur点所到之处所有的点次
// 返回cur点次
// 缓存order
// key : 某一个点的点次,之前算过了!
// value : 点次是多少
public static Record f(DirectedGraphNode cur, HashMap<DirectedGraphNode, Record> order) { public static Record f(DirectedGraphNode cur, HashMap<DirectedGraphNode, Record> order) {
if (order.containsKey(cur)) { if (order.containsKey(cur)) {
return order.get(cur); return order.get(cur);
} }
// cur的点次之前没算过
long nodes = 0; long nodes = 0;
for (DirectedGraphNode next : cur.neighbors) { for (DirectedGraphNode next : cur.neighbors) {
nodes += f(next, order).nodes; nodes += f(next, order).nodes;

@ -1,4 +1,4 @@
package class10; package class10_16;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -10,7 +10,9 @@ public class Code03_TopologySort {
// directed graph and no loop // directed graph and no loop
public static List<Node> sortedTopology(Graph graph) { public static List<Node> sortedTopology(Graph graph) {
// key 某个节点 value 剩余的入度
HashMap<Node, Integer> inMap = new HashMap<>(); HashMap<Node, Integer> inMap = new HashMap<>();
// 只有剩余入度为0的点才进入这个队列
Queue<Node> zeroInQueue = new LinkedList<>(); Queue<Node> zeroInQueue = new LinkedList<>();
for (Node node : graph.nodes.values()) { for (Node node : graph.nodes.values()) {
inMap.put(node, node.in); inMap.put(node, node.in);

@ -1,4 +1,4 @@
package class10; package class10_16;
import java.util.Collection; import java.util.Collection;
import java.util.Comparator; import java.util.Comparator;
@ -83,6 +83,7 @@ public class Code04_Kruskal {
public static Set<Edge> kruskalMST(Graph graph) { public static Set<Edge> kruskalMST(Graph graph) {
UnionFind unionFind = new UnionFind(); UnionFind unionFind = new UnionFind();
unionFind.makeSets(graph.nodes.values()); unionFind.makeSets(graph.nodes.values());
// 从小的边到大的边,依次弹出,小根堆!
PriorityQueue<Edge> priorityQueue = new PriorityQueue<>(new EdgeComparator()); PriorityQueue<Edge> priorityQueue = new PriorityQueue<>(new EdgeComparator());
for (Edge edge : graph.edges) { // M 条边 for (Edge edge : graph.edges) { // M 条边
priorityQueue.add(edge); // O(logM) priorityQueue.add(edge); // O(logM)

@ -1,4 +1,4 @@
package class10; package class10_16;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashSet; import java.util.HashSet;
@ -23,7 +23,11 @@ public class Code05_Prim {
// 哪些点被解锁出来了 // 哪些点被解锁出来了
HashSet<Node> nodeSet = new HashSet<>(); HashSet<Node> nodeSet = new HashSet<>();
Set<Edge> result = new HashSet<>(); // 依次挑选的的边在result里 Set<Edge> result = new HashSet<>(); // 依次挑选的的边在result里
for (Node node : graph.nodes.values()) { // 随便挑了一个点 for (Node node : graph.nodes.values()) { // 随便挑了一个点
// node 是开始点 // node 是开始点
if (!nodeSet.contains(node)) { if (!nodeSet.contains(node)) {

@ -1,4 +1,4 @@
package class10; package class10_16;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -10,15 +10,17 @@ public class Code06_Dijkstra {
public static HashMap<Node, Integer> dijkstra1(Node from) { public static HashMap<Node, Integer> dijkstra1(Node from) {
HashMap<Node, Integer> distanceMap = new HashMap<>(); HashMap<Node, Integer> distanceMap = new HashMap<>();
distanceMap.put(from, 0); distanceMap.put(from, 0);
// 打过对号的点
HashSet<Node> selectedNodes = new HashSet<>(); HashSet<Node> selectedNodes = new HashSet<>();
Node minNode = getMinDistanceAndUnselectedNode(distanceMap, selectedNodes); Node minNode = getMinDistanceAndUnselectedNode(distanceMap, selectedNodes);
while (minNode != null) { while (minNode != null) {
// 原始点 -> minNode(跳转点) 最小距离distance
int distance = distanceMap.get(minNode); int distance = distanceMap.get(minNode);
for (Edge edge : minNode.edges) { for (Edge edge : minNode.edges) {
Node toNode = edge.to; Node toNode = edge.to;
if (!distanceMap.containsKey(toNode)) { if (!distanceMap.containsKey(toNode)) {
distanceMap.put(toNode, distance + edge.weight); distanceMap.put(toNode, distance + edge.weight);
} else { } else { // toNode
distanceMap.put(edge.to, Math.min(distanceMap.get(toNode), distance + edge.weight)); distanceMap.put(edge.to, Math.min(distanceMap.get(toNode), distance + edge.weight));
} }
} }

@ -1,4 +1,4 @@
package class10; package class10_16;
public class Edge { public class Edge {
public int weight; public int weight;

@ -1,4 +1,4 @@
package class10; package class10_16;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;

@ -1,17 +1,21 @@
package class10; package class10_16;
public class GraphGenerator { public class GraphGenerator {
// matrix 所有的边 // matrix 所有的边
// N*3 的矩阵 // N*3 的矩阵
// [weight, from节点上面的值to节点上面的值] // [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(); Graph graph = new Graph();
for (int i = 0; i < matrix.length; i++) { for (int i = 0; i < matrix.length; i++) {
// matrix[0][0], matrix[0][1] matrix[0][2] // 拿到每一条边, matrix[i]
Integer weight = matrix[i][0]; int weight = matrix[i][0];
Integer from = matrix[i][1]; int from = matrix[i][1];
Integer to = matrix[i][2]; int to = matrix[i][2];
if (!graph.nodes.containsKey(from)) { if (!graph.nodes.containsKey(from)) {
graph.nodes.put(from, new Node(from)); graph.nodes.put(from, new Node(from));
} }

@ -1,8 +1,8 @@
package class10; package class10_16;
import java.util.ArrayList; import java.util.ArrayList;
// 点结构的描述 A 0 // 点结构的描述
public class Node { public class Node {
public int value; public int value;
public int in; public int in;

@ -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<Node, Integer> dijkstra1(Node from) {
HashMap<Node, Integer> distanceMap = new HashMap<>();
distanceMap.put(from, 0);
// 打过对号的点
HashSet<Node> 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<Node, Integer> distanceMap, HashSet<Node> touchedNodes) {
Node minNode = null;
int minDistance = Integer.MAX_VALUE;
for (Entry<Node, Integer> 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<Node, Integer> heapIndexMap;
// key 某一个节点, value 从源节点出发到该节点的目前最小距离
private HashMap<Node, Integer> 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<Node, Integer> dijkstra2(Node head, int size) {
NodeHeap nodeHeap = new NodeHeap(size);
nodeHeap.addOrUpdateOrIgnore(head, 0);
HashMap<Node, Integer> 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;
}
}

@ -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;
}
}

@ -0,0 +1,14 @@
package class10_17;
import java.util.HashMap;
import java.util.HashSet;
public class Graph {
public HashMap<Integer, Node> nodes;
public HashSet<Edge> edges;
public Graph() {
nodes = new HashMap<>();
edges = new HashSet<>();
}
}

@ -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<Node> nexts;
public ArrayList<Edge> edges;
public Node(int value) {
this.value = value;
in = 0;
out = 0;
nexts = new ArrayList<>();
edges = new ArrayList<>();
}
}

@ -1,4 +1,4 @@
package class11; package class11_17;
import java.util.Stack; import java.util.Stack;

@ -1,4 +1,4 @@
package class11; package class11_17;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;

@ -1,4 +1,4 @@
package class11; package class11_17;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;

@ -1,4 +1,4 @@
package class11; package class11_17;
import java.util.Stack; import java.util.Stack;

@ -1,4 +1,4 @@
package class11; package class11_17;
public class Code06_ConvertToLetterString { public class Code06_ConvertToLetterString {
@ -34,38 +34,9 @@ public class Code06_ConvertToLetterString {
return res; return res;
} }
return process(str, i + 1); 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) { if (s == null || s.length() == 0) {
return 0; return 0;
} }
@ -94,8 +65,8 @@ public class Code06_ConvertToLetterString {
} }
public static void main(String[] args) { public static void main(String[] args) {
System.out.println(number("11111")); System.out.println(number("2132082"));
System.out.println(dpWays2("11111")); System.out.println(dp("2132082"));
} }
} }

@ -1,4 +1,4 @@
package class11; package class11_17;
public class Code07_Knapsack { public class Code07_Knapsack {

@ -1,4 +1,4 @@
package class11; package class11_17;
public class Code08_CardsInLine { public class Code08_CardsInLine {

@ -1,4 +1,4 @@
package class11; package class11_17;
public class Code09_NQueens { public class Code09_NQueens {

@ -0,0 +1,106 @@
package class12;
import java.util.TreeSet;
/*
* arrarr
*
* 便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<Integer> 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<Integer> 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("测试结束");
}
}

@ -0,0 +1,122 @@
package class12;
import java.util.TreeSet;
/*
* arrarr
* 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<Integer> 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<Integer> 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("测试结束");
}
}
Loading…
Cancel
Save