diff --git a/src/leo/class02_03/LinkedList.java b/src/leo/class02_03/LinkedList.java index 44f1b09..40cd5fc 100644 --- a/src/leo/class02_03/LinkedList.java +++ b/src/leo/class02_03/LinkedList.java @@ -169,7 +169,7 @@ public class LinkedList { if (head == null) { return null; } - Node pre = head; + Node pre = null; Node next = null; while (head != null) { next = head.next; @@ -180,6 +180,21 @@ public class LinkedList { return pre; } + public static Node reverseNode11(Node head) { + if (head == null || head.next == null) { + return head; + } + Node pre = null; + Node next = null; + while (head != null) { + next = head.next; + head.next = pre; + pre = head; + head = next; + } + return pre; + } + public static DoubleNode reverseDoubleNode(DoubleNode head) { DoubleNode pre = null; DoubleNode next; @@ -263,7 +278,7 @@ public class LinkedList { if (head == null) { return null; } - DoubleNode pre = head; + DoubleNode pre = null; DoubleNode next = null; while (head != null) { next = head.next; @@ -276,6 +291,23 @@ public class LinkedList { } + + public static DoubleNode reverseDoubleNode7(DoubleNode head){ + if (head == null || head.next == null) { + return head; + } + DoubleNode pre = null; + DoubleNode next = null; + while (head != null) { + next = head.next; + head.pre = head.next; + head.next = pre; + pre = head; + head = next; + } + return pre; + } + /** * 功能描述 : 随机生成单链表 * @author Leo @@ -406,14 +438,14 @@ public class LinkedList { for (int i = 0; i < testTime; i++) { Node head = randomNode(maxSize, range); List nodeList = nodeToList(head); - Node node = reverseNode10(head); + Node node = reverseNode11(head); if (!verifyReverseListAndNode(nodeList, node)) { System.out.println("nodeFuck!!"); break; } DoubleNode doubleNodeHead = randomDoubleNode(maxSize, range); List doubleNodeList = DoubleNodeToList(doubleNodeHead); - DoubleNode doubleNode = reverseDoubleNode6(doubleNodeHead); + DoubleNode doubleNode = reverseDoubleNode7(doubleNodeHead); if (!verifyReverseListAndDoubleNode(doubleNodeList, doubleNode)) { System.out.println("doubleNodeFuck!!"); break; diff --git a/src/leo/class06_09/IsPalindromeList.java b/src/leo/class06_09/IsPalindromeList.java new file mode 100644 index 0000000..5a7b511 --- /dev/null +++ b/src/leo/class06_09/IsPalindromeList.java @@ -0,0 +1,423 @@ +package leo.class06_09; + +import com.sun.org.apache.xpath.internal.functions.FuncFalse; + +import javax.print.attribute.standard.NumberUp; +import java.util.Stack; + +/** + * @author Leo + * @ClassName IsPalindromeList + * @DATE 2020/12/2 8:54 下午 + * @Description + */ +public class IsPalindromeList { + + public static boolean isPalindromeList(Node head) { + if (head == null || head.next == null) { + return true; + } + boolean verify = true; + Node mid = findMid(head); + Node midNext = mid.next; + mid.next = null; + midNext = reverseNode(midNext); + Node cur = head; + Node curReverseNode = midNext; + while (cur != null && curReverseNode != null) { + if (cur.value != curReverseNode.value) { + verify = false; + break; + } + cur = cur.next; + curReverseNode = curReverseNode.next; + } + midNext = reverseNode(midNext); + mid.next = midNext; + return verify; + + } + + public static Node findMid(Node head) { + if (head == null || head.next == null || head.next.next == null) { + return head; + } + Node slow = head; + Node fast = head; + while (fast.next != null && fast.next.next != null) { + slow = slow.next; + fast = fast.next.next; + } + return slow; + } + + public static Node reverseNode(Node head) { + Node pre = null; + Node next = null; + while (head != null) { + next = head.next; + head.next = pre; + pre = head; + head = next; + } + return pre; + } + + public static boolean isPalindromeListByStack(Node head) { + boolean verify = true; + Stack stack = new Stack<>(); + Node cur = head; + while (cur != null) { + stack.push(cur); + cur = cur.next; + } + cur = head; + while (!stack.isEmpty()) { + if (stack.pop().value != cur.value) { + verify = false; + } + cur = cur.next; + } + return verify; + } + + + public static boolean isPalindromeList1(Node head){ + if (head == null || head.next == null) { + return false; + } + Node n1 = head; + Node n2 = head; + while (n2.next != null && n2.next.next != null) { + n1 = n1.next; + n2 = n2.next.next; + } + n2 = n1.next; + n1.next = null; + Node n3 = null; + while (n2 != null) { + n3 = n2.next; + n2.next = n1; + n1 = n2; + n2 = n3; + } + n3 = n1; + n2 = head; + boolean verify = true; + while (n2 != null && n1 != null) { + if (n2.value != n1.value) { + verify = false; + break; + } + n1 = n1.next; + n2 = n2.next; + } + + + n1 = n3.next; + n3.next = null; + while (n1 != null) { + n2 = n1.next; + n1.next = n3; + n3 = n1; + n1 = n2; + } + return verify; + } + + + public static boolean isPalindromeList2(Node head){ + if (head == null || head.next == null) { + return true; + } + Node n1 = head; + Node n2 = head; + //findMid + while (n2.next != null && n2.next.next != null) { + n1 = n1.next; + n2 = n2.next.next; + } + //n1 mid + //reverseNode half node + n2 = n1.next; //n2 is after half head + //cut n1 is prefix half endNode + //and n1 is after half tail + n1.next = null; + //temp is next + Node n3 = null; + while (n2 != null) { + n3 = n2.next; + n2.next = n1; + n1 = n2; + n2 = n3; + } + //n2 is head of the flipped node + //n1 is the last node in the after half + n3 = n1; //save n1 + n2 = head; + boolean verify = true; + while (n1 != null && n2 != null) { + if (n1.value != n2.value) { + + verify = false; + break; + } + n1 = n1.next; + n2 = n2.next; + } + //reverseNode again + n1 = n3.next; + n3.next = null; + while (n1 != null) { + n2 = n1.next; + n1.next = n3; + n3 = n1; + n1 = n2; + } + + return verify; + + } + + + public static boolean isPalindromeList3(Node head) { + if (head == null || head.next == null) { + return true; + } + Node n1 = head; + Node n2 = head; + while (n2.next != null && n2.next.next != null) { + n1 = n1.next; + n2 = n2.next; + } + //n1 is mid; + n2 = n1.next; + n1.next = null; + Node n3 = null; + while (n2 != null) { + n3 = n2.next; + n2.next = n1; + n1 = n2; + n2 = n3; + } + n3 = n1; + n2 = head; + boolean verify = true; + while (n1 != null && n2 != null) { + if (n1.value != n2.value) { + verify = false; + break; + } + n1 = n1.next; + n2 = n2.next; + } + n1 = n3.next; + n3.next = null; + while (n1 != null) { + n2 = n1.next; + n1.next = n3; + n3 = n1; + n1 = n2; + } + return verify; + + } + + public static boolean isPalindromeList4(Node head) { + if (head == null || head.next == null) { + return true; + } + Node n1 = head; + Node n2 = head; + while (n2.next != null && n2.next.next != null) { + n1 = n1.next; + n2 = n2.next.next; + } + //reverseNode + //n1 is mid + n2 = n1.next; + n1.next = null; + Node n3 = null; + while (n2 != null) { + n3 = n2.next; + n2.next = n1; + n1 = n2; + n2 = n3; + } + n3 = n1; //n1 is right + n2 = head; //left + boolean verify = true; + while (n1 != null && n2 != null) { + if (n1.value != n2.value) { + verify = false; + break; + } + n1 = n1.next; + n2 = n2.next; + } + n1 = n3.next; + n3.next = null; + while (n1 != null) { + n2 = n1.next; + n1.next = n3; + n3 = n1; + n1 = n2; + } + return verify; + } + + public static boolean isPalindromeList5(Node head) { + if (head == null || head.next == null) { + return true; + } + Node n1 = head; + Node n2 = head; + while (n2.next != null && n2.next.next != null) { + n1 = n1.next; + n2 = n2.next.next; + } + //n1 is mid + n2 = n1.next; + n1.next = null; + Node n3 = null; + while (n2 != null) { + n3 = n2.next; + n2.next = n1; + n1 = n2; + n2 = n3; + } + //n1 is head after flipping the linked list ; + //n1 and n2 end node is the same one + //n3 temporary save n1; + n3 = n1; + n2 = head; + boolean verify = true; + while (n1 != null && n2 != null) { + if (n1.value != n2.value) { + verify = false; + } + n1 = n1.next; + n2 = n2.next; + } + //if ListNode length is Even n2 is null , + //if ListNode length is odd n1 and n2 both null + n2 = n3.next; + n3.next = null; + //reverse again + while (n2 != null) { + n1 = n2.next; + n2.next = n3; + n3 = n2; + n2 = n1; + } + return verify; + } + +} + + +class IsPalindromeListMain { + + public static void main(String[] args){ + int testTime = 1000; + int maxSize = 3; + int range = 100; + boolean a; + boolean b; + System.out.println("start!"); + + for (int i = 0; i < testTime; i++) { + Node originNode = generateRandomNode(maxSize, range); + Node head = copyNode(originNode); + b = IsPalindromeList.isPalindromeListByStack(head); + a = IsPalindromeList.isPalindromeList5(head); + if (!isEqualsNode(head, originNode)) { + System.out.println("not equals node!"); + } + if (a != b) { + System.out.println(a); + System.out.println(b); + System.out.println("fuck!"); + } + } + System.out.println("end!"); + + } + + private static boolean isEqualsNode(Node n1, Node n2) { + if (n1 == null && n2 == null) { + return true; + } + if (n1 != null && n2 == null) { + return false; + } + + if (n1 == null && n2 != null) { + return false; + } + while (n1 != null && n2 != null) { + if (n1.value != n2.value) { + return false; + } + n1 = n1.next; + n2 = n2.next; + } + + return true; + } + + public static Node generateRandomNode(int maxSize, int range) { + Node head = new Node(randomInt(range)); + Node cur = head; + for (int i = 0; i < maxSize; i++) { + Node node = new Node(randomInt(range)); + cur.next = node; + cur = cur.next; + } + if (Math.random() > 0.5) { + return head; + } + Node copyNode = copyNode(head); + copyNode = reverseNode(copyNode); + if (copyNode.next != null && Math.random() > 0.5) { + cur.next = copyNode.next; + }else{ + cur.next = copyNode; + } + return head; + } + + private static Node copyNode(Node head) { + Node copyHead = new Node(head.value); + Node curCopy = copyHead; + Node curHead = head.next; + while (curHead.next != null) { + curCopy.next = new Node(curHead.value); + curHead = curHead.next; + curCopy = curCopy.next; + } + curCopy.next = new Node(curHead.value); + return copyHead; + } + + + private static Node reverseNode(Node head) { + if (head == null || head.next == null) { + return head; + } + Node pre = null; + Node next = null; + while (head != null) { + next = head.next; + head.next = pre; + pre = head; + head = next; + } + return pre; + } + + public static int randomInt(int range) { + return (int) ((range * Math.random() + 1) - (range * Math.random() + 1)); + } + +} diff --git a/src/leo/class06_09/LinkedListMid.java b/src/leo/class06_09/LinkedListMid.java new file mode 100644 index 0000000..8d461fb --- /dev/null +++ b/src/leo/class06_09/LinkedListMid.java @@ -0,0 +1,210 @@ +package leo.class06_09; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Leo + * @ClassName class06_09 + * @DATE 2020/12/2 6:42 下午 + * @Description 找链表中点 + */ +class LinkedListMid { + + + //奇数长度返回中点,偶数长度返回上中点 + static class FindMidOrUpMidNode{ + public static Node findMid(Node head){ + if (head == null || head.next == null || head.next.next == null) { + return head; + } + Node slow = head; + Node fast = head; + while (fast.next != null && fast.next.next != null) { + slow = slow.next; + fast = fast.next.next; + } + return slow; + } + } + + //奇数长度返回中点,偶数长度返回下中点 + static class FindMidOrDownMidNode{ + public static Node findMid(Node head) { + if (head == null || head.next == null) { + + return head; + } + Node slow = head.next; + Node fast = head.next; + while (fast.next != null && fast.next.next != null) { + slow = slow.next; + fast = fast.next.next; + } + return slow; + } + + } + + //奇数长度返回中点前一个,偶数长度返回上中点前一个 + static class FindMidOrUpMidPreNode { + public static Node findMid(Node head) { + if (head==null||head.next==null||head.next.next==null){ + return head; + } + Node slow = head; + Node fast = head.next.next; + while (fast.next != null && fast.next.next != null) { + slow = slow.next; + fast = fast.next.next; + } + return slow; + } + } + + //奇数长度返回中点前一个,偶数长度返回下中点前一个 + static class FindMidOrDownMidPreNode { + public static Node findMid(Node head) { + if (head == null || head.next == null || head.next.next == null) { + return head; + } + Node slow = head; + Node fast = head.next; + while (fast.next != null && fast.next.next != null) { + slow = slow.next; + fast = fast.next.next; + } + return slow; + } + + } + + +} + +class Right{ + //奇数长度返回中点,偶数长度返回上中点 + public static Node findMidOrUpMidNode(Node head) { + if (head == null) { + return head; + } + List list = new ArrayList<>(); + Node cur = head; + while (cur != null) { + list.add(cur); + cur = cur.next; + } + return list.get((list.size()-1) /2); + } + + //奇数长度返回中点,偶数长度返回下中点 + public static Node findMidOrDownMidNode(Node head) { + if (head == null) { + return head; + } + List list = new ArrayList<>(); + Node cur = head; + while (cur != null) { + list.add(cur); + cur = cur.next; + } + return list.get(list.size()/2); + } + //奇数长度返回中点前一个,偶数长度返回上中点前一个 + public static Node findMidOrUpMidPreNode(Node head){ + if (head == null) { + return head; + } + List list = new ArrayList<>(); + Node cur = head; + while (cur != null) { + list.add(cur); + cur = cur.next; + } + return list.get((list.size()-3)/2); + + } + //奇数长度返回中点前一个,偶数长度返回下中点前一个 + public static Node findMidOrDownMidPreNode(Node head){ + if (head == null) { + return head; + } + List list = new ArrayList<>(); + Node cur = head; + while (cur != null) { + list.add(cur); + cur = cur.next; + } + return list.get((list.size()-2)/2); + + } +} + +class LinkedListMidMain{ + + + public static Node randomNode(int maxSize, int range) { + int length = (int)(maxSize * Math.random()) + 1; + Node head = new Node((int) (range * Math.random()) + 1 - (int) (range * Math.random()) + 1); + Node cur = head; + for (int i = 0; i < length; i++) { + Node node = new Node((int) (range * Math.random()) + 1 - (int) (range * Math.random()) + 1); + cur.next = node; + cur = cur.next; + } + return head; + } + + public static void main(String[] args){ + int testTime = 100000; + int maxSize = 80; + int range = 100; + Node node; + Node nodeTest; + System.out.println("start!"); + + for (int i = 0; i < testTime; i++) { + Node head = randomNode(maxSize, range); + node = LinkedListMid.FindMidOrUpMidNode.findMid(head); + nodeTest = Right.findMidOrUpMidNode(head); + if (!node.equals(nodeTest)){ + System.out.println("findMidOrUpMidNode"); + System.out.println(node.toString()); + System.out.println(nodeTest.toString()); + break; + } + node = LinkedListMid.FindMidOrDownMidNode.findMid(head); + nodeTest = Right.findMidOrDownMidNode(head); + if (!node.equals(nodeTest)){ + System.out.println("findMidOrDownMidNode"); + System.out.println(node.toString()); + System.out.println(nodeTest.toString()); + break; + } + node = LinkedListMid.FindMidOrUpMidPreNode.findMid(head); + nodeTest = Right.findMidOrUpMidPreNode(head); + if (!node.equals(nodeTest)){ + System.out.println("findMidOrUpMidPreNode"); + System.out.println(node.toString()); + System.out.println(nodeTest.toString()); + break; + } + node = LinkedListMid.FindMidOrDownMidPreNode.findMid(head); + nodeTest = Right.findMidOrDownMidPreNode(head); + if (!node.equals(nodeTest)){ + System.out.println("findMidOrDownMidPreNode"); + System.out.println(node.toString()); + System.out.println(nodeTest.toString()); + break; + } + } + System.out.println("end!"); + + } + + + + + + +} diff --git a/src/leo/class06_09/Node.java b/src/leo/class06_09/Node.java new file mode 100644 index 0000000..a325757 --- /dev/null +++ b/src/leo/class06_09/Node.java @@ -0,0 +1,40 @@ +package leo.class06_09; + +/** + * @author Leo + * @ClassName Node + * @DATE 2020/12/2 8:56 下午 + * @Description + */ +public class Node{ + int value; + Node next; + public Node(int v){ + this.value = v; + } + + @Override + public boolean equals(Object object) { + if (this == object) return true; + if (object == null || getClass() != object.getClass()) return false; + + Node node = (Node) object; + + if (value != node.value) return false; + return next.equals(node.next); + } + + @Override + public int hashCode() { + int result = value; + result = 31 * result + next.hashCode(); + return result; + } + + @Override + public String toString() { + return "Node{" + + "value=" + value + + '}'; + } +} diff --git a/src/leo/class06_09/SmallerEqualBigger.java b/src/leo/class06_09/SmallerEqualBigger.java new file mode 100644 index 0000000..c3a2054 --- /dev/null +++ b/src/leo/class06_09/SmallerEqualBigger.java @@ -0,0 +1,195 @@ +package leo.class06_09; + +/** + * @author Leo + * @ClassName SmallerEqualBigger + * @DATE 2020/12/3 5:56 下午 + * @Description 将链表根据给定值,按小左大右放置 + */ +public class SmallerEqualBigger { + + + + static class NodePartitionByArray{ + + public static Node nodePartitionByArray(Node head, int target) { + if (head == null || head.next == null) { + return head; + } + int i = 0; + Node cur = head; + while (cur != null) { + cur = cur.next; + i++; + } + Node[] nodes = new Node[i]; + cur = head; + for (i = 0; i < nodes.length; i++) { + nodes[i] = cur; + cur = cur.next; + } + partitionNode(nodes, target); + for (i = 1; i < nodes.length; i++) { + nodes[i - 1].next = nodes[i]; + } + nodes[i - 1].next = null; + return nodes[0]; + } + + public static void partitionNode(Node[] nodes, int target) { + int small = -1; + int big = nodes.length; + int index = 0; + while (index < big) { + if (nodes[index].value < target) { + swapNodeArray(nodes, index++, ++small); + } else if (nodes[index].value > target) { + swapNodeArray(nodes, index, --big); + }else { + index++; + } + } + } + + public static void swapNodeArray(Node[] nodes, int i, int j) { + + if (i == j) { + return; + } + Node temp = nodes[i]; + nodes[i] = nodes[j]; + nodes[j] = temp; + } + } + + public static Node listPartition(Node head, int target) { + if (head == null || head.next == null) { + return head; + } + Node sH = null; + Node sT = null; + Node bH = null; + Node bT = null; + Node next = null; + while (head != null) { + next = head.next; + head.next = null; + if (head.value < target) { + if (sH == null) { + sH = head; + sT = head; + }else{ + sT.next = head; + sT = head; + } + } else if (head.value > target) { + if (bH == null) { + bH = head; + bT = head; + }else { + bT.next = head; + bT = head; + } + + } else if (head.value == target) { + if (bH == null) { + bH = head; + bT = head; + }else{ + head.next = bH; + bH = head; + } + } + head = next; + } + if (sT == null) { + return bH; + } else { + sT.next = bH; + return sH; + } + } +} + +class SmallerEqualBigger_Main{ + public static void printLinkedList(Node node) { + System.out.print("Linked List: "); + while (node != null) { + System.out.print(node.value + " "); + node = node.next; + } + System.out.println(); + } + + public static void main(String[] args) { + + int maxSize = 5; + int range = 100; + Node originNode = generateRandomNode(maxSize, range); + printLinkedList(originNode); + // head1 = listPartition1(head1, 4); + int i = randomInt(range); + System.out.println(i); + originNode = SmallerEqualBigger.listPartition(originNode, i); + printLinkedList(originNode); + + } + + public static Node generateRandomNode(int maxSize, int range) { + Node head = new Node(randomInt(range)); + Node cur = head; + for (int i = 0; i < maxSize; i++) { + Node node = new Node(randomInt(range)); + cur.next = node; + cur = cur.next; + } + if (Math.random() > 0.5) { + return head; + } + Node copyNode = copyNode(head); + copyNode = reverseNode(copyNode); + if (copyNode.next != null && Math.random() > 0.5) { + cur.next = copyNode.next; + }else{ + cur.next = copyNode; + } + return head; + } + + private static Node copyNode(Node head) { + Node copyHead = new Node(head.value); + Node curCopy = copyHead; + Node curHead = head.next; + while (curHead.next != null) { + curCopy.next = new Node(curHead.value); + curHead = curHead.next; + curCopy = curCopy.next; + } + curCopy.next = new Node(curHead.value); + return copyHead; + } + + + private static Node reverseNode(Node head) { + if (head == null || head.next == null) { + return head; + } + Node pre = null; + Node next = null; + while (head != null) { + next = head.next; + head.next = pre; + pre = head; + head = next; + } + return pre; + } + + public static int randomInt(int range) { + return (int) ((range * Math.random() + 1) - (range * Math.random() + 1)); + } + +} + + +