From a4f6aedabf03ac0f2c849e901d2ceae8f7fd3042 Mon Sep 17 00:00:00 2001 From: Hien Doan Date: Wed, 7 Aug 2024 16:00:06 +0700 Subject: [PATCH 1/2] Add solutions for Topic 2: Linked List --- .../dkhien/01ReverseLinkedList.java | 27 +++++++++ .../dkhien/02MergeTwoSortedLists.java | 40 +++++++++++++ Topic2_LinkedList/dkhien/03ReorderList.java | 44 ++++++++++++++ .../dkhien/04RemoveNthNodeFromEndOfList.java | 36 ++++++++++++ .../dkhien/05CopyListWithRandomPointer.java | 58 +++++++++++++++++++ Topic2_LinkedList/dkhien/06AddTwoNumbers.java | 55 ++++++++++++++++++ .../dkhien/07LinkedListCycle.java | 29 ++++++++++ 7 files changed, 289 insertions(+) create mode 100644 Topic2_LinkedList/dkhien/01ReverseLinkedList.java create mode 100644 Topic2_LinkedList/dkhien/02MergeTwoSortedLists.java create mode 100644 Topic2_LinkedList/dkhien/03ReorderList.java create mode 100644 Topic2_LinkedList/dkhien/04RemoveNthNodeFromEndOfList.java create mode 100644 Topic2_LinkedList/dkhien/05CopyListWithRandomPointer.java create mode 100644 Topic2_LinkedList/dkhien/06AddTwoNumbers.java create mode 100644 Topic2_LinkedList/dkhien/07LinkedListCycle.java diff --git a/Topic2_LinkedList/dkhien/01ReverseLinkedList.java b/Topic2_LinkedList/dkhien/01ReverseLinkedList.java new file mode 100644 index 0000000..bca1dd7 --- /dev/null +++ b/Topic2_LinkedList/dkhien/01ReverseLinkedList.java @@ -0,0 +1,27 @@ +class Solution { + public ListNode reverseList(ListNode head) { + if (head == null) return null; + if (head.next == null) return head; + + ListNode newHead = new ListNode(); + newHead.next = null; + + while (head.next != null) { + // Copy value to current node of the new list + newHead.val = head.val; + + // Create the next node + ListNode next = new ListNode(); + next.val = head.next.val; + + // Connect next node to current node (next -> current) to reverse + next.next = newHead; + + // Iterate + newHead = next; + head = head.next; + } + + return newHead; + } +} \ No newline at end of file diff --git a/Topic2_LinkedList/dkhien/02MergeTwoSortedLists.java b/Topic2_LinkedList/dkhien/02MergeTwoSortedLists.java new file mode 100644 index 0000000..e14a5b8 --- /dev/null +++ b/Topic2_LinkedList/dkhien/02MergeTwoSortedLists.java @@ -0,0 +1,40 @@ +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ +class Solution { + public ListNode mergeTwoLists(ListNode list1, ListNode list2) { + ListNode result = new ListNode(); + ListNode current = result; + + while (list1 != null && list2 != null) { + // Choose the smaller value to add to the result list + if (list1.val <= list2.val) { + current.next = list1; + list1 = list1.next; + } else { + current.next = list2; + list2 = list2.next; + } + + // Iterate + current = current.next; + } + + // Add the remaining nodes to the result list + if (list1 != null) { + current.next = list1; + } else if (list2 != null) { + current.next = list2; + } + + return result.next; + + } +} \ No newline at end of file diff --git a/Topic2_LinkedList/dkhien/03ReorderList.java b/Topic2_LinkedList/dkhien/03ReorderList.java new file mode 100644 index 0000000..27e248c --- /dev/null +++ b/Topic2_LinkedList/dkhien/03ReorderList.java @@ -0,0 +1,44 @@ +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ +class Solution { + public void reorderList(ListNode head) { + List nodeList = new ArrayList<>(); + ListNode temp = head; + + while (temp != null) { + nodeList.add(temp); + temp = temp.next; + } + + // Traverse half of the list + for (int i = 0; i < nodeList.size() / 2; i++) { + ListNode node = nodeList.get(i); + + // The next node to link to should have index size - 1 - i + ListNode nextNode = nodeList.get(nodeList.size() - 1 - i); + + if (i == nodeList.size() / 2 - 1 && nodeList.size() % 2 == 0) { + // If the list has even number of nodes, the next node of the middle node should be null + nextNode.next = null; + } else if (i == nodeList.size() / 2 - 1 && nodeList.size() % 2 != 0) { + // If the list has odd number of nodes, the next node of the middle node should be the last node + nextNode.next = node.next; + nextNode.next.next = null; + } else { + // Normal case + nextNode.next = node.next; + } + + // Link the current node to the next node + node.next = nextNode; + } + } +} \ No newline at end of file diff --git a/Topic2_LinkedList/dkhien/04RemoveNthNodeFromEndOfList.java b/Topic2_LinkedList/dkhien/04RemoveNthNodeFromEndOfList.java new file mode 100644 index 0000000..de623ee --- /dev/null +++ b/Topic2_LinkedList/dkhien/04RemoveNthNodeFromEndOfList.java @@ -0,0 +1,36 @@ +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ +class Solution { + public ListNode removeNthFromEnd(ListNode head, int n) { + if (head == null || head.next == null) return null; + ListNode ptr1 = head; + ListNode ptr2 = head; + + // ptr2 starts first, n steps ahead of ptr1 + for (int i = 0; i < n; i++) { + if (ptr2.next == null) { + return head.next; + } + ptr2 = ptr2.next; + } + + // Move ptr1 and ptr2 until ptr2 reaches the end + while (ptr2.next != null) { + ptr1 = ptr1.next; + ptr2 = ptr2.next; + } + + // ptr1 should now be at the (n-1)th node from the end -> remove the next node + ptr1.next = ptr1.next.next; + + return head; + } +} \ No newline at end of file diff --git a/Topic2_LinkedList/dkhien/05CopyListWithRandomPointer.java b/Topic2_LinkedList/dkhien/05CopyListWithRandomPointer.java new file mode 100644 index 0000000..436a67f --- /dev/null +++ b/Topic2_LinkedList/dkhien/05CopyListWithRandomPointer.java @@ -0,0 +1,58 @@ +/* +// Definition for a Node. +class Node { + int val; + Node next; + Node random; + + public Node(int val) { + this.val = val; + this.next = null; + this.random = null; + } +} +*/ + +class Solution { + public Node copyRandomList(Node head) { + if (head == null) return null; + + // Map original node to its clone + Map originalToClone = new HashMap<>(); + Node res = new Node(0); + Node dummy = res; + + // Idea: Clone the list linearly and avoid duplicate cloning by using a map + while (head != null) { + // Clone next node, if in map use the existing clone + Node nextClone; + if (originalToClone.containsKey(head)) { + nextClone = originalToClone.get(head); + } else { + nextClone = new Node(head.val); + originalToClone.put(head, nextClone); + } + + dummy.next = nextClone; + + // Clone random node, if in map use the existing clone + Node randomClone = null; + if (head.random != null) { + if (originalToClone.containsKey(head.random)) { + randomClone = originalToClone.get(head.random); + } else { + randomClone = new Node(head.random.val); + originalToClone.put(head.random, randomClone); + } + } + + dummy.next.random = randomClone; + + // Iterate + dummy = nextClone; + head = head.next; + } + + return res.next; + } +} \ No newline at end of file diff --git a/Topic2_LinkedList/dkhien/06AddTwoNumbers.java b/Topic2_LinkedList/dkhien/06AddTwoNumbers.java new file mode 100644 index 0000000..9fe6f3d --- /dev/null +++ b/Topic2_LinkedList/dkhien/06AddTwoNumbers.java @@ -0,0 +1,55 @@ +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ +class Solution { + public ListNode addTwoNumbers(ListNode l1, ListNode l2) { + ListNode dummy = new ListNode(); + ListNode current = dummy; + int carry = 0; + + // Idea: Add each digit like in elementary school + while (true) { + + // Calculate the sum of the current digits + // If one of the lists is null, the value of that list is 0 + int sum; + if (l1 == null && l2 != null) { + sum = l2.val + carry; + l2 = l2.next; + } else if (l1 != null && l2 == null) { + sum = l1.val + carry; + l1 = l1.next; + } else if (l1 != null && l2 != null) { + sum = l1.val + l2.val + carry; + l1 = l1.next; + l2 = l2.next; + } else { + break; + } + + // Calculate the carry and the value of the current digit + carry = sum / 10; + sum %= 10; + + // Create a new node and link it to the result list + ListNode res = new ListNode(sum); + current.next = res; + current = res; + } + + // Add the last carry if any + if (carry > 0) { + ListNode carryNode = new ListNode(carry); + current.next = carryNode; + } + + return dummy.next; + } +} \ No newline at end of file diff --git a/Topic2_LinkedList/dkhien/07LinkedListCycle.java b/Topic2_LinkedList/dkhien/07LinkedListCycle.java new file mode 100644 index 0000000..a3302e3 --- /dev/null +++ b/Topic2_LinkedList/dkhien/07LinkedListCycle.java @@ -0,0 +1,29 @@ +/** + * Definition for singly-linked list. + * class ListNode { + * int val; + * ListNode next; + * ListNode(int x) { + * val = x; + * next = null; + * } + * } + */ +public class Solution { + public boolean hasCycle(ListNode head) { + if (head == null) return false; + ListNode slow = head; + ListNode fast = head; + + // Idea: The fast pointer will surely meet the slow pointer if there is a cycle + while (fast != null && fast.next != null) { + slow = slow.next; + fast = fast.next.next; + if (slow == fast) { + return true; + } + } + + return false; + } +} \ No newline at end of file From a576d2240e207cb28d044b91f2e439ac1595ee32 Mon Sep 17 00:00:00 2001 From: Hien Doan Date: Wed, 7 Aug 2024 16:04:41 +0700 Subject: [PATCH 2/2] Add time and space complexity analysis for Topic 2 solutions --- .../dkhien/01ReverseLinkedList.java | 3 +++ .../dkhien/02MergeTwoSortedLists.java | 13 +++---------- Topic2_LinkedList/dkhien/03ReorderList.java | 13 +++---------- .../dkhien/04RemoveNthNodeFromEndOfList.java | 13 +++---------- .../dkhien/05CopyListWithRandomPointer.java | 16 ++-------------- Topic2_LinkedList/dkhien/06AddTwoNumbers.java | 13 +++---------- Topic2_LinkedList/dkhien/07LinkedListCycle.java | 17 +++++------------ 7 files changed, 22 insertions(+), 66 deletions(-) diff --git a/Topic2_LinkedList/dkhien/01ReverseLinkedList.java b/Topic2_LinkedList/dkhien/01ReverseLinkedList.java index bca1dd7..04b0f0a 100644 --- a/Topic2_LinkedList/dkhien/01ReverseLinkedList.java +++ b/Topic2_LinkedList/dkhien/01ReverseLinkedList.java @@ -1,3 +1,6 @@ +// Time Complexity: O(n) +// Space Complexity: O(1) + class Solution { public ListNode reverseList(ListNode head) { if (head == null) return null; diff --git a/Topic2_LinkedList/dkhien/02MergeTwoSortedLists.java b/Topic2_LinkedList/dkhien/02MergeTwoSortedLists.java index e14a5b8..2f42424 100644 --- a/Topic2_LinkedList/dkhien/02MergeTwoSortedLists.java +++ b/Topic2_LinkedList/dkhien/02MergeTwoSortedLists.java @@ -1,13 +1,6 @@ -/** - * Definition for singly-linked list. - * public class ListNode { - * int val; - * ListNode next; - * ListNode() {} - * ListNode(int val) { this.val = val; } - * ListNode(int val, ListNode next) { this.val = val; this.next = next; } - * } - */ +// Time Complexity: O(n) +// Space Complexity: O(1) + class Solution { public ListNode mergeTwoLists(ListNode list1, ListNode list2) { ListNode result = new ListNode(); diff --git a/Topic2_LinkedList/dkhien/03ReorderList.java b/Topic2_LinkedList/dkhien/03ReorderList.java index 27e248c..af676bb 100644 --- a/Topic2_LinkedList/dkhien/03ReorderList.java +++ b/Topic2_LinkedList/dkhien/03ReorderList.java @@ -1,13 +1,6 @@ -/** - * Definition for singly-linked list. - * public class ListNode { - * int val; - * ListNode next; - * ListNode() {} - * ListNode(int val) { this.val = val; } - * ListNode(int val, ListNode next) { this.val = val; this.next = next; } - * } - */ +// Time Complexity: O(n) +// Space Complexity: O(n) + class Solution { public void reorderList(ListNode head) { List nodeList = new ArrayList<>(); diff --git a/Topic2_LinkedList/dkhien/04RemoveNthNodeFromEndOfList.java b/Topic2_LinkedList/dkhien/04RemoveNthNodeFromEndOfList.java index de623ee..9ee4ac8 100644 --- a/Topic2_LinkedList/dkhien/04RemoveNthNodeFromEndOfList.java +++ b/Topic2_LinkedList/dkhien/04RemoveNthNodeFromEndOfList.java @@ -1,13 +1,6 @@ -/** - * Definition for singly-linked list. - * public class ListNode { - * int val; - * ListNode next; - * ListNode() {} - * ListNode(int val) { this.val = val; } - * ListNode(int val, ListNode next) { this.val = val; this.next = next; } - * } - */ +// Time Complexity: O(n) +// Space Complexity: O(1) + class Solution { public ListNode removeNthFromEnd(ListNode head, int n) { if (head == null || head.next == null) return null; diff --git a/Topic2_LinkedList/dkhien/05CopyListWithRandomPointer.java b/Topic2_LinkedList/dkhien/05CopyListWithRandomPointer.java index 436a67f..791e2a3 100644 --- a/Topic2_LinkedList/dkhien/05CopyListWithRandomPointer.java +++ b/Topic2_LinkedList/dkhien/05CopyListWithRandomPointer.java @@ -1,17 +1,5 @@ -/* -// Definition for a Node. -class Node { - int val; - Node next; - Node random; - - public Node(int val) { - this.val = val; - this.next = null; - this.random = null; - } -} -*/ +// Time Complexity: O(n) +// Space Complexity: O(n) class Solution { public Node copyRandomList(Node head) { diff --git a/Topic2_LinkedList/dkhien/06AddTwoNumbers.java b/Topic2_LinkedList/dkhien/06AddTwoNumbers.java index 9fe6f3d..1e56e0d 100644 --- a/Topic2_LinkedList/dkhien/06AddTwoNumbers.java +++ b/Topic2_LinkedList/dkhien/06AddTwoNumbers.java @@ -1,13 +1,6 @@ -/** - * Definition for singly-linked list. - * public class ListNode { - * int val; - * ListNode next; - * ListNode() {} - * ListNode(int val) { this.val = val; } - * ListNode(int val, ListNode next) { this.val = val; this.next = next; } - * } - */ +// Time Complexity: O(n) +// Space Complexity: O(1) + class Solution { public ListNode addTwoNumbers(ListNode l1, ListNode l2) { ListNode dummy = new ListNode(); diff --git a/Topic2_LinkedList/dkhien/07LinkedListCycle.java b/Topic2_LinkedList/dkhien/07LinkedListCycle.java index a3302e3..6cd0e3f 100644 --- a/Topic2_LinkedList/dkhien/07LinkedListCycle.java +++ b/Topic2_LinkedList/dkhien/07LinkedListCycle.java @@ -1,17 +1,10 @@ -/** - * Definition for singly-linked list. - * class ListNode { - * int val; - * ListNode next; - * ListNode(int x) { - * val = x; - * next = null; - * } - * } - */ +// Time Complexity: O(n) +// Space Complexity: O(1) + public class Solution { public boolean hasCycle(ListNode head) { - if (head == null) return false; + if (head == null) + return false; ListNode slow = head; ListNode fast = head;