From f0f5f85c0125c6db2d8f8b2bd97be4054fc0163b Mon Sep 17 00:00:00 2001 From: Chen Xu Date: Fri, 19 Aug 2022 15:38:29 -0400 Subject: [PATCH] Day 4 - Linked List --- LinkedList.java | 245 +++++++++++++++++++++++++++++++++++++++++++- utils/ListNode.java | 10 ++ 2 files changed, 251 insertions(+), 4 deletions(-) diff --git a/LinkedList.java b/LinkedList.java index d4d2f29..eb2b383 100644 --- a/LinkedList.java +++ b/LinkedList.java @@ -2,6 +2,9 @@ public class LinkedList { public static void main(String[] args) { + LinkedList l = new LinkedList(); + + l.mergeSort(ListNode.fromArray(new int[] { 4, 3, 2, 1 })); } /** @@ -104,10 +107,10 @@ public ListNode insert(ListNode head, int value) { } /** - * Merge Two Sorted Linked Lists - *

- * Merge two sorted lists into one large sorted list. - */ + * Merge Two Sorted Linked Lists + *

+ * Merge two sorted lists into one large sorted list. + */ public ListNode merge(ListNode one, ListNode two) { ListNode dummy = new ListNode(0); ListNode cur = dummy; @@ -130,4 +133,238 @@ public ListNode merge(ListNode one, ListNode two) { return dummy.next; } + + /** + * ReOrder Linked List + *

+ * Reorder the given singly-linked list N1 -> N2 -> N3 -> N4 -> … -> Nn -> null + * to be N1- > Nn -> N2 -> Nn-1 -> N3 -> Nn-2 -> … -> null + */ + public ListNode reorder(ListNode head) { + if (head == null || head.next == null) { + return head; + } + + // get midpoint + ListNode slow = head; + ListNode fast = head; + + while (fast.next != null && fast.next.next != null) { + slow = slow.next; + fast = fast.next.next; + } + + ListNode head2 = slow.next; + slow.next = null; + + // reverse LinkedList 2 + ListNode prev = null; + ListNode next; + while (head2 != null) { + next = head2.next; + head2.next = prev; + prev = head2; + head2 = next; + } + + // merge head with prev + ListNode dummy = new ListNode(0); + ListNode cur = dummy; + while (prev != null) { + cur.next = head; + head = head.next; + cur.next.next = prev; + prev = prev.next; + cur = cur.next.next; + } + if (head != null) { + cur.next = head; + } + + return dummy.next; + } + + /** + * Partition Linked List + *

+ * Given a linked list and a target value T, partition it such that all nodes + * less than T are listed before the nodes larger than or equal to target value + * T. The original relative order of the nodes in each of the two partitions + * should be preserved. + */ + public ListNode partition(ListNode head, int target) { + ListNode dummy1 = new ListNode(0); + ListNode dummy2 = new ListNode(0); + ListNode cur1 = dummy1; + ListNode cur2 = dummy2; + ListNode cur = head; + + while (cur != null) { + if (cur.value < target) { + cur1.next = cur; + cur1 = cur; + } else { + cur2.next = cur; + cur2 = cur; + } + cur = cur.next; + } + cur2.next = null; + cur1.next = dummy2.next; + return dummy1.next; + } + + /** + * Merge Sort Linked List + *

+ * Given a singly-linked list, where each node contains an integer value, sort + * it in ascending order. The merge sort algorithm should be used to solve this + * problem. + */ + public ListNode mergeSort(ListNode head) { + if (head == null || head.next == null) { + return head; + } + ListNode slow = head; + ListNode fast = head; + while (fast.next != null && fast.next.next != null) { + slow = slow.next; + fast = fast.next.next; + } + + ListNode head2 = slow.next; + slow.next = null; + + head = mergeSort(head); + head2 = mergeSort(head2); + + ListNode newHead = merge2(head, head2); + return newHead; + } + + private ListNode merge2(ListNode head1, ListNode head2) { + ListNode dummy = new ListNode(0); + ListNode cur = dummy; + while (head1 != null && head2 != null) { + if (head1.value < head2.value) { + cur.next = head1; + head1 = head1.next; + } else { + cur.next = head2; + head2 = head2.next; + } + cur = cur.next; + } + if (head1 != null) { + cur.next = head1; + } else { + cur.next = head2; + } + + return dummy.next; + } + + /** + * Add Two Numbers + *

+ * You are given two linked lists representing two non-negative numbers. The + * digits are stored in reverse order and each of their nodes contain a single + * digit. Add the two numbers and return it as a linked list. + */ + public ListNode addTwoNumbers(ListNode l1, ListNode l2) { + ListNode dummy = new ListNode(0); + ListNode cur = dummy; + int carry = 0; + while (l1 != null && l2 != null) { + int sum = l1.value + l2.value + carry; + cur.next = new ListNode(sum % 10); + carry = sum / 10; + l1 = l1.next; + l2 = l2.next; + cur = cur.next; + } + + if (l1 != null || l2 != null) { + l1 = (l2 != null) ? l2 : l1; + while (l1 != null) { + int sum = l1.value + carry; + cur.next = new ListNode(sum % 10); + carry = sum / 10; + l1 = l1.next; + cur = cur.next; + } + } + + if (carry != 0) { + cur.next = new ListNode(carry); + } + + return dummy.next; + } + + /** + * Check If Linked List Is Palindrome + *

+ * Given a linked list, check whether it is a palindrome. + */ + public boolean isPalindrome(ListNode head) { + if (head == null || head.next == null) { + return true; + } + + // find middle point + ListNode slow = head; + ListNode fast = head; + + while (fast.next != null && fast.next.next != null) { + slow = slow.next; + fast = fast.next.next; + } + + ListNode head2 = slow.next; + slow.next = null; + + // reverse second half + ListNode prev = null; + ListNode next; + while (head2 != null) { + next = head2.next; + head2.next = prev; + prev = head2; + head2 = next; + } + + // check palindrome + + while (prev != null) { + if (head.value != prev.value) { + return false; + } + head = head.next; + prev = prev.next; + } + + return true; + } + + /** + * Remove Linked List Elements + *

+ * Remove all elements from a linked list of integers that have value val. + */ + public ListNode removeElements(ListNode head, int val) { + ListNode dummy = new ListNode(0); + ListNode cur = dummy; + while (head != null) { + if (head.value != val) { + cur.next = head; + head = head.next; + cur = cur.next; + } else { + head = head.next; + } + } + cur.next = null; + return dummy.next; + } } diff --git a/utils/ListNode.java b/utils/ListNode.java index f344f03..d387450 100644 --- a/utils/ListNode.java +++ b/utils/ListNode.java @@ -7,4 +7,14 @@ public class ListNode { public ListNode(int value) { this.value = value; } + + public static ListNode fromArray(int[] array) { + ListNode dummy = new ListNode(0); + ListNode cur = dummy; + for (int i : array) { + cur.next = new ListNode(i); + cur = cur.next; + } + return dummy.next; + } }