From 1862154ce0189ff3d958e659c9c59a35584eb4a8 Mon Sep 17 00:00:00 2001 From: algorithmzuo <64469262+algorithmzuo@users.noreply.github.com> Date: Sun, 10 May 2020 17:10:22 +0800 Subject: [PATCH] update on 2020-05-10 --- src/class08/Code05_MaxSubBSTHead.java | 19 ++-- src/class08/Code06_IsCBT.java | 43 ++++++-- src/class08/Code07_lowestAncestor.java | 22 ++-- src/class09/Code01_LowestLexicography.java | 9 +- src/class09/Code02_Light.java | 16 ++- src/class09/Code04_BestArrange.java | 8 ++ src/class10/Code01_UnionFind.java | 21 ++-- src/class10/Code03_TopologySort.java | 4 +- src/class10/Code04_Kruskal.java | 44 +------- src/class10/Code05_Prim.java | 17 +-- src/class10/Code06_Dijkstra.java | 20 ++-- src/class10/Code07_MergeUsers.java | 118 +++++++++++++++++++++ src/class10/Graph.java | 2 +- src/class10/GraphGenerator.java | 9 +- src/class10/Node.java | 1 + src/class11/Code01_Hanoi.java | 46 ++++++++ 16 files changed, 290 insertions(+), 109 deletions(-) create mode 100644 src/class10/Code07_MergeUsers.java diff --git a/src/class08/Code05_MaxSubBSTHead.java b/src/class08/Code05_MaxSubBSTHead.java index 70c01bb..b9fa1a4 100644 --- a/src/class08/Code05_MaxSubBSTHead.java +++ b/src/class08/Code05_MaxSubBSTHead.java @@ -56,6 +56,7 @@ public class Code05_MaxSubBSTHead { return process(head).maxSubBSTHead; } + // 每一棵子树 public static class Info { public Node maxSubBSTHead; public int maxSubBSTSize; @@ -70,14 +71,14 @@ public class Code05_MaxSubBSTHead { } } - public static Info process(Node head) { - if (head == null) { + public static Info process(Node X) { + if (X == null) { return null; } - Info leftInfo = process(head.left); - Info rightInfo = process(head.right); - int min = head.value; - int max = head.value; + Info leftInfo = process(X.left); + Info rightInfo = process(X.right); + int min = X.value; + int max = X.value; Node maxSubBSTHead = null; int maxSubBSTSize = 0; if (leftInfo != null) { @@ -94,9 +95,9 @@ public class Code05_MaxSubBSTHead { maxSubBSTSize = rightInfo.maxSubBSTSize; } } - if ((leftInfo == null ? true : (leftInfo.maxSubBSTHead == head.left && leftInfo.max < head.value)) - && (rightInfo == null ? true : (rightInfo.maxSubBSTHead == head.right && rightInfo.min > head.value))) { - maxSubBSTHead = head; + if ((leftInfo == null ? true : (leftInfo.maxSubBSTHead == X.left && leftInfo.max < X.value)) + && (rightInfo == null ? true : (rightInfo.maxSubBSTHead == X.right && rightInfo.min > X.value))) { + maxSubBSTHead = X; maxSubBSTSize = (leftInfo == null ? 0 : leftInfo.maxSubBSTSize) + (rightInfo == null ? 0 : rightInfo.maxSubBSTSize) + 1; } diff --git a/src/class08/Code06_IsCBT.java b/src/class08/Code06_IsCBT.java index 6fc3df4..a2aaf40 100644 --- a/src/class08/Code06_IsCBT.java +++ b/src/class08/Code06_IsCBT.java @@ -30,7 +30,9 @@ public class Code06_IsCBT { r = head.right; if ( // 如果遇到了不双全的节点之后,又发现当前节点不是叶节点 - (leaf && !(l == null && r == null)) || (l == null && r != null)) { + (leaf && (l != null || r != null)) || (l == null && r != null) + + ) { return false; } if (l != null) { @@ -53,6 +55,7 @@ public class Code06_IsCBT { return process(head).isCBT; } + // 对每一棵子树,是否是满二叉树、是否是完全二叉树、高度 public static class Info { public boolean isFull; public boolean isCBT; @@ -65,28 +68,48 @@ public class Code06_IsCBT { } } - public static Info process(Node head) { - if (head == null) { + public static Info process(Node X) { + if (X == null) { return new Info(true, true, 0); } - Info leftInfo = process(head.left); - Info rightInfo = process(head.right); + Info leftInfo = process(X.left); + Info rightInfo = process(X.right); + + + int height = Math.max(leftInfo.height, rightInfo.height) + 1; - boolean isFull = leftInfo.isFull && rightInfo.isFull && leftInfo.height == rightInfo.height; + + + boolean isFull = leftInfo.isFull + && + rightInfo.isFull + && leftInfo.height == rightInfo.height; + + boolean isCBT = false; if (isFull) { isCBT = true; - } else { + } else { // 以x为头整棵树,不满 if (leftInfo.isCBT && rightInfo.isCBT) { - if (leftInfo.isCBT && rightInfo.isFull && leftInfo.height == rightInfo.height + 1) { + + + if (leftInfo.isCBT + && rightInfo.isFull + && leftInfo.height == rightInfo.height + 1) { isCBT = true; } - if (leftInfo.isFull && rightInfo.isFull && leftInfo.height == rightInfo.height + 1) { + if (leftInfo.isFull + && + rightInfo.isFull + && leftInfo.height == rightInfo.height + 1) { isCBT = true; } - if (leftInfo.isFull && rightInfo.isCBT && leftInfo.height == rightInfo.height) { + if (leftInfo.isFull + && rightInfo.isCBT && leftInfo.height == rightInfo.height) { isCBT = true; } + + } } return new Info(isFull, isCBT, height); diff --git a/src/class08/Code07_lowestAncestor.java b/src/class08/Code07_lowestAncestor.java index a97f4be..6a9affd 100644 --- a/src/class08/Code07_lowestAncestor.java +++ b/src/class08/Code07_lowestAncestor.java @@ -20,6 +20,7 @@ public class Code07_lowestAncestor { if (head == null) { return null; } + // key的父节点是value HashMap parentMap = new HashMap<>(); parentMap.put(head, null); fillParentMap(head, parentMap); @@ -52,6 +53,7 @@ public class Code07_lowestAncestor { return process(head, o1, o2).ans; } + // 任何子树, public static class Info { public Node ans; public boolean findO1; @@ -64,15 +66,19 @@ public class Code07_lowestAncestor { } } - public static Info process(Node head, Node o1, Node o2) { - if (head == null) { + public static Info process(Node X, Node o1, Node o2) { + if (X == null) { return new Info(null, false, false); } - Info leftInfo = process(head.left, o1, o2); - Info rightInfo = process(head.right, o1, o2); - - boolean findO1 = head == o1 || leftInfo.findO1 || rightInfo.findO1; - boolean findO2 = head == o2 || leftInfo.findO2 || rightInfo.findO2; + Info leftInfo = process(X.left, o1, o2); + Info rightInfo = process(X.right, o1, o2); + boolean findO1 = X == o1 || leftInfo.findO1 || rightInfo.findO1; + boolean findO2 = X == o2 || leftInfo.findO2 || rightInfo.findO2; + // O1和O2最初的交汇点在哪? + // 1) 在左树上已经提前交汇了 + // 2) 在右树上已经提前交汇了 + // 3) 没有在左树或者右树上提前交汇,O1 O2 全了 + // 4) Node ans = null; if (leftInfo.ans != null) { ans = leftInfo.ans; @@ -82,7 +88,7 @@ public class Code07_lowestAncestor { } if (ans == null) { if (findO1 && findO2) { - ans = head; + ans = X; } } return new Info(ans, findO1, findO2); diff --git a/src/class09/Code01_LowestLexicography.java b/src/class09/Code01_LowestLexicography.java index d3f7b57..3768253 100644 --- a/src/class09/Code01_LowestLexicography.java +++ b/src/class09/Code01_LowestLexicography.java @@ -23,7 +23,14 @@ public class Code01_LowestLexicography { return lowest; } - public static void process(String[] strs, HashSet use, String path, ArrayList all) { + // strs里放着所有的字符串 + // 已经使用过的字符串的下标,在use里登记了,不要再使用了 + // 之前使用过的字符串,拼接成了-> path + // 用all收集所有可能的拼接结果 + public static void process(String[] strs, + HashSet use, + String path, + ArrayList all) { if (use.size() == strs.length) { all.add(path); } else { diff --git a/src/class09/Code02_Light.java b/src/class09/Code02_Light.java index b892240..981419d 100644 --- a/src/class09/Code02_Light.java +++ b/src/class09/Code02_Light.java @@ -11,17 +11,23 @@ public class Code02_Light { return process(road.toCharArray(), 0, new HashSet<>()); } + // str[index....]位置,自由选择放灯还是不放灯 + // str[0..index-1]位置呢?已经做完决定了,那些放了灯的位置,存在lights里 + // 要求选出能照亮所有.的方案,并且在这些有效的方案中,返回最少需要几个灯 public static int process(char[] str, int index, HashSet lights) { - if (index == str.length) { + if (index == str.length) { // 结束的时候 for (int i = 0; i < str.length; i++) { - if (str[i] != 'X') { - if (!lights.contains(i - 1) && !lights.contains(i) && !lights.contains(i + 1)) { + if (str[i] != 'X') { // 当前位置是点的话 + if (!lights.contains(i - 1) + && !lights.contains(i) + && !lights.contains(i + 1)) { return Integer.MAX_VALUE; } } } return lights.size(); - } else { + } else { // str还没结束 + // i X . int no = process(str, index + 1, lights); int yes = Integer.MAX_VALUE; if (str[index] == '.') { @@ -40,7 +46,7 @@ public class Code02_Light { while (index < str.length) { if (str[index] == 'X') { index++; - } else { + } else { // i -> . light++; if (index + 1 == str.length) { break; diff --git a/src/class09/Code04_BestArrange.java b/src/class09/Code04_BestArrange.java index 2b5711a..7cf290a 100644 --- a/src/class09/Code04_BestArrange.java +++ b/src/class09/Code04_BestArrange.java @@ -22,11 +22,19 @@ public class Code04_BestArrange { return process(programs, 0, 0); } + // 还剩什么会议都放在programs里 + // done 之前已经安排了多少会议,数量 + // timeLine目前来到的时间点是什么 + + // 目前来到timeLine的时间点,已经安排了done多的会议,剩下的会议programs可以自由安排 + // 返回能安排的最多会议数量 public static int process(Program[] programs, int done, int timeLine) { if (programs.length == 0) { return done; } + // 还有会议可以选择 int max = done; + // 当前安排的会议是什么会,每一个都枚举 for (int i = 0; i < programs.length; i++) { if (programs[i].start >= timeLine) { Program[] next = copyButExcept(programs, i); diff --git a/src/class10/Code01_UnionFind.java b/src/class10/Code01_UnionFind.java index 3421427..f7f6422 100644 --- a/src/class10/Code01_UnionFind.java +++ b/src/class10/Code01_UnionFind.java @@ -20,14 +20,15 @@ public class Code01_UnionFind { public HashMap, Integer> sizeMap; public UnionSet(List values) { - for (V value : values) { - Node node = new Node<>(value); - nodes.put(value, node); + for (V cur : values) { + Node node = new Node<>(cur); + nodes.put(cur, node); parents.put(node, node); sizeMap.put(node, 1); } } + // 从点cur开始,一直往上找,找到不能再往上的代表点,返回 public Node findFather(Node cur) { Stack> path = new Stack<>(); while (cur != parents.get(cur)) { @@ -57,15 +58,11 @@ public class Code01_UnionFind { if (aHead != bHead) { int aSetSize = sizeMap.get(aHead); int bSetSize = sizeMap.get(bHead); - if (aSetSize >= bSetSize) { - parents.put(bHead, aHead); - sizeMap.put(aHead, aSetSize + bSetSize); - sizeMap.remove(bHead); - } else { - parents.put(aHead, bHead); - sizeMap.put(bHead, aSetSize + bSetSize); - sizeMap.remove(aHead); - } + Node big = aSetSize >= bSetSize ? aHead : bHead; + Node small = big == aHead ? bHead : aHead; + parents.put(small, big); + sizeMap.put(big, aSetSize + bSetSize); + sizeMap.remove(small); } } } diff --git a/src/class10/Code03_TopologySort.java b/src/class10/Code03_TopologySort.java index 51ba075..43533de 100644 --- a/src/class10/Code03_TopologySort.java +++ b/src/class10/Code03_TopologySort.java @@ -13,8 +13,10 @@ public class Code03_TopologySort { // key:某一个node // value:剩余的入度 HashMap inMap = new HashMap<>(); - // 入度为0的点,才能进这个队列 + // 剩余入度为0的点,才能进这个队列 Queue zeroInQueue = new LinkedList<>(); + + for (Node node : graph.nodes.values()) { inMap.put(node, node.in); if (node.in == 0) { diff --git a/src/class10/Code04_Kruskal.java b/src/class10/Code04_Kruskal.java index caa1da0..e95a1fc 100644 --- a/src/class10/Code04_Kruskal.java +++ b/src/class10/Code04_Kruskal.java @@ -1,58 +1,16 @@ package class10; -import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; -import java.util.List; import java.util.PriorityQueue; import java.util.Set; import java.util.Stack; //undirected graph only public class Code04_Kruskal { - - public static class MySets{ - public HashMap> setMap; - public MySets(List nodes) { - for(Node cur : nodes) { - List set = new ArrayList(); - set.add(cur); - setMap.put(cur, set); - } - } - - - public boolean isSameSet(Node from, Node to) { - List fromSet = setMap.get(from); - List toSet = setMap.get(to); - return fromSet == toSet; - } - - - public void union(Node from, Node to) { - List fromSet = setMap.get(from); - List toSet = setMap.get(to); - for(Node toNode : toSet) { - fromSet.add(toNode); - setMap.put(toNode, fromSet); - } - } - } - - - - - - - - - - - - - + // Union-Find Set public static class UnionFind { // key 某一个节点, value key节点往上的节点 diff --git a/src/class10/Code05_Prim.java b/src/class10/Code05_Prim.java index def87d6..9564d3b 100644 --- a/src/class10/Code05_Prim.java +++ b/src/class10/Code05_Prim.java @@ -19,22 +19,23 @@ public class Code05_Prim { public static Set primMST(Graph graph) { // 解锁的边进入小根堆 - PriorityQueue priorityQueue = new PriorityQueue<>( - new EdgeComparator()); - HashSet set = new HashSet<>(); + PriorityQueue priorityQueue = new PriorityQueue<>(new EdgeComparator()); + + // 哪些点被解锁出来了 + HashSet nodeSet = new HashSet<>(); Set result = new HashSet<>(); // 依次挑选的的边在result里 for (Node node : graph.nodes.values()) { // 随便挑了一个点 // node 是开始点 - if (!set.contains(node)) { - set.add(node); + if (!nodeSet.contains(node)) { + nodeSet.add(node); for (Edge edge : node.edges) { // 由一个点,解锁所有相连的边 priorityQueue.add(edge); } while (!priorityQueue.isEmpty()) { Edge edge = priorityQueue.poll(); // 弹出解锁的边中,最小的边 Node toNode = edge.to; // 可能的一个新的点 - if (!set.contains(toNode)) { // 不含有的时候,就是新的点 - set.add(toNode); + if (!nodeSet.contains(toNode)) { // 不含有的时候,就是新的点 + nodeSet.add(toNode); result.add(edge); for (Edge nextEdge : toNode.edges) { priorityQueue.add(nextEdge); @@ -42,7 +43,7 @@ public class Code05_Prim { } } } - //break; + // break; } return result; } diff --git a/src/class10/Code06_Dijkstra.java b/src/class10/Code06_Dijkstra.java index ed66369..b561cf3 100644 --- a/src/class10/Code06_Dijkstra.java +++ b/src/class10/Code06_Dijkstra.java @@ -7,15 +7,16 @@ import java.util.Map.Entry; // no negative weight public class Code06_Dijkstra { - public static HashMap dijkstra1(Node head) { + public static HashMap dijkstra1(Node from) { // 从head出发到所有点的最小距离 // key : 从head出发到达key // value : 从head出发到达key的最小距离 // 如果在表中,没有T的记录,含义是从head出发到T这个点的距离为正无穷 HashMap distanceMap = new HashMap<>(); - distanceMap.put(head, 0); + distanceMap.put(from, 0); // 已经求过距离的节点,存在selectedNodes中,以后再也不碰 HashSet selectedNodes = new HashSet<>(); + // from 0 Node minNode = getMinDistanceAndUnselectedNode(distanceMap, selectedNodes); while (minNode != null) { int distance = distanceMap.get(minNode); @@ -24,7 +25,8 @@ public class Code06_Dijkstra { if (!distanceMap.containsKey(toNode)) { distanceMap.put(toNode, distance + edge.weight); } else { - distanceMap.put(edge.to, Math.min(distanceMap.get(toNode), distance + edge.weight)); + distanceMap.put(edge.to, + Math.min(distanceMap.get(toNode), distance + edge.weight)); } } selectedNodes.add(minNode); @@ -33,7 +35,9 @@ public class Code06_Dijkstra { return distanceMap; } - public static Node getMinDistanceAndUnselectedNode(HashMap distanceMap, HashSet touchedNodes) { + public static Node getMinDistanceAndUnselectedNode( + HashMap distanceMap, + HashSet touchedNodes) { Node minNode = null; int minDistance = Integer.MAX_VALUE; for (Entry entry : distanceMap.entrySet()) { @@ -59,7 +63,7 @@ public class Code06_Dijkstra { public static class NodeHeap { private Node[] nodes; // 实际的堆结构 - // key 某一个node, value 上面数组中的位置 + // key 某一个node, value 上面堆中的位置 private HashMap heapIndexMap; // key 某一个节点, value 从源节点出发到该节点的目前最小距离 private HashMap distanceMap; @@ -103,7 +107,8 @@ public class Code06_Dijkstra { } private void insertHeapify(Node node, int index) { - while (distanceMap.get(nodes[index]) < distanceMap.get(nodes[(index - 1) / 2])) { + while (distanceMap.get(nodes[index]) + < distanceMap.get(nodes[(index - 1) / 2])) { swap(index, (index - 1) / 2); index = (index - 1) / 2; } @@ -115,7 +120,8 @@ public class Code06_Dijkstra { 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; + smallest = distanceMap.get(nodes[smallest]) + < distanceMap.get(nodes[index]) ? smallest : index; if (smallest == index) { break; } diff --git a/src/class10/Code07_MergeUsers.java b/src/class10/Code07_MergeUsers.java new file mode 100644 index 0000000..95faab8 --- /dev/null +++ b/src/class10/Code07_MergeUsers.java @@ -0,0 +1,118 @@ +package class10; + +import java.util.HashMap; +import java.util.List; +import java.util.Stack; + +public class Code07_MergeUsers { + + public static class Node { + V value; + + public Node(V v) { + value = v; + } + } + + public static class UnionSet { + public HashMap> nodes; + public HashMap, Node> parents; + public HashMap, Integer> sizeMap; + + public UnionSet(List values) { + for (V cur : values) { + Node node = new Node<>(cur); + nodes.put(cur, node); + parents.put(node, node); + sizeMap.put(node, 1); + } + } + + // 从点cur开始,一直往上找,找到不能再往上的代表点,返回 + public Node findFather(Node cur) { + Stack> path = new Stack<>(); + while (cur != parents.get(cur)) { + path.push(cur); + cur = parents.get(cur); + } + // cur头节点 + while (!path.isEmpty()) { + parents.put(path.pop(), cur); + } + return cur; + } + + public boolean isSameSet(V a, V b) { + if (!nodes.containsKey(a) || !nodes.containsKey(b)) { + return false; + } + return findFather(nodes.get(a)) == findFather(nodes.get(b)); + } + + public void union(V a, V b) { + if (!nodes.containsKey(a) || !nodes.containsKey(b)) { + return; + } + Node aHead = findFather(nodes.get(a)); + Node bHead = findFather(nodes.get(b)); + if (aHead != bHead) { + int aSetSize = sizeMap.get(aHead); + int bSetSize = sizeMap.get(bHead); + Node big = aSetSize >= bSetSize ? aHead : bHead; + Node small = big == aHead ? bHead : aHead; + parents.put(small, big); + sizeMap.put(big, aSetSize + bSetSize); + sizeMap.remove(small); + } + } + + + public int getSetNum() { + return sizeMap.size(); + } + + } + + public static class User { + public String a; + public String b; + public String c; + + public User(String a, String b, String c) { + this.a = a; + this.b = b; + this.c = c; + } + + } + + // (1,10,13) (2,10,37) (400,500,37) + // 如果两个user,a字段一样、或者b字段一样、或者c字段一样,就认为是一个人 + // 请合并users,返回合并之后的用户数量 + public static int mergeUsers(List users) { + UnionSet unionFind = new UnionSet<>(users); + HashMap mapA = new HashMap<>(); + HashMap mapB = new HashMap<>(); + HashMap mapC = new HashMap<>(); + for(User user : users) { + if(mapA.containsKey(user.a)) { + unionFind.union(user, mapA.get(user.a)); + }else { + mapA.put(user.a, user); + } + if(mapB.containsKey(user.b)) { + unionFind.union(user, mapB.get(user.b)); + }else { + mapB.put(user.b, user); + } + if(mapC.containsKey(user.c)) { + unionFind.union(user, mapC.get(user.c)); + }else { + mapC.put(user.c, user); + } + } + // 向并查集询问,合并之后,还有多少个集合? + return unionFind.getSetNum(); + } + +} diff --git a/src/class10/Graph.java b/src/class10/Graph.java index 484504f..b70e007 100644 --- a/src/class10/Graph.java +++ b/src/class10/Graph.java @@ -6,7 +6,7 @@ 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/GraphGenerator.java b/src/class10/GraphGenerator.java index dc6a0b8..1180e20 100644 --- a/src/class10/GraphGenerator.java +++ b/src/class10/GraphGenerator.java @@ -7,10 +7,11 @@ public class GraphGenerator { // [weight, from节点上面的值,to节点上面的值] public static Graph createGraph(Integer[][] matrix) { Graph graph = new Graph(); - for (int i = 0; i < matrix.length; i++) { // matrix[0][0], matrix[0][1] matrix[0][2] - Integer from = matrix[i][0]; - Integer to = matrix[i][1]; - Integer weight = matrix[i][2]; + 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]; 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 f56e977..d022d12 100644 --- a/src/class10/Node.java +++ b/src/class10/Node.java @@ -2,6 +2,7 @@ package class10; import java.util.ArrayList; +// 点结构的描述 A 0 public class Node { public int value; public int in; diff --git a/src/class11/Code01_Hanoi.java b/src/class11/Code01_Hanoi.java index b840f8b..1872653 100644 --- a/src/class11/Code01_Hanoi.java +++ b/src/class11/Code01_Hanoi.java @@ -1,11 +1,14 @@ package class11; +import java.util.Stack; + public class Code01_Hanoi { public static void hanoi1(int n) { leftToRight(n); } + // 请把1~N层圆盘 从左 -> 右 public static void leftToRight(int n) { if (n == 1) { System.out.println("Move 1 from left to right"); @@ -16,6 +19,7 @@ public class Code01_Hanoi { midToRight(n - 1); } + // 请把1~N层圆盘 从左 -> 中 public static void leftToMid(int n) { if (n == 1) { System.out.println("Move 1 from left to mid"); @@ -83,12 +87,54 @@ public class Code01_Hanoi { } } + public static class Record { + public boolean finish1; + public int base; + public String from; + public String to; + public String other; + + public Record(boolean f1, int b, String f, String t, String o) { + finish1 = false; + base = b; + from = f; + to = t; + other = o; + } + } + + public static void hanoi3(int N) { + if (N < 1) { + return; + } + Stack stack = new Stack<>(); + stack.add(new Record(false, N, "left", "right", "mid")); + while (!stack.isEmpty()) { + Record cur = stack.pop(); + if (cur.base == 1) { + System.out.println("Move 1 from " + cur.from + " to " + cur.to); + if (!stack.isEmpty()) { + stack.peek().finish1 = true; + } + } else { + if (!cur.finish1) { + stack.push(cur); + stack.push(new Record(false, cur.base - 1, cur.from, cur.other, cur.to)); + } else { + System.out.println("Move " + cur.base + " from " + cur.from + " to " + cur.to); + stack.push(new Record(false, cur.base - 1, cur.other, cur.to, cur.from)); + } + } + } + } + public static void main(String[] args) { int n = 3; hanoi1(n); System.out.println("============"); hanoi2(n); System.out.println("============"); + hanoi3(n); } }