From 9bfe0d9f45b4ac77a76c604a57671c3ea17a7f18 Mon Sep 17 00:00:00 2001 From: aikhelis Date: Fri, 31 Jan 2025 23:37:09 +0000 Subject: [PATCH 01/27] ts-3: linked list reversal --- .../Linked Lists/linked_list_reversal.ts | 27 +++++++++++++++++++ .../linked_list_reversal_recursive.ts | 24 +++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 typescript/Linked Lists/linked_list_reversal.ts create mode 100644 typescript/Linked Lists/linked_list_reversal_recursive.ts diff --git a/typescript/Linked Lists/linked_list_reversal.ts b/typescript/Linked Lists/linked_list_reversal.ts new file mode 100644 index 0000000..2c5d745 --- /dev/null +++ b/typescript/Linked Lists/linked_list_reversal.ts @@ -0,0 +1,27 @@ +// Definition of ListNode: +class ListNode { + val: number; + next: TNode; + constructor(val: number, next: TNode = null){ + this.val = val; + this.next = next; + } +} +type TNode = ListNode | null; + +function linked_list_reversal(head: TNode): TNode { + let curr_node: TNode = head; + let prev_node: TNode = null; + // Reverse the direction of each node's pointer until 'curr_node' + // is null. + while (curr_node !== null){ + const next_node: TNode = curr_node.next; + curr_node.next = prev_node; + prev_node = curr_node; + curr_node = next_node; + } + // 'prev_node' will be pointing at the head of the reversed linked + // list. + return prev_node; +} + diff --git a/typescript/Linked Lists/linked_list_reversal_recursive.ts b/typescript/Linked Lists/linked_list_reversal_recursive.ts new file mode 100644 index 0000000..31ee834 --- /dev/null +++ b/typescript/Linked Lists/linked_list_reversal_recursive.ts @@ -0,0 +1,24 @@ +/* Definition of ListNode: +class ListNode { + val: number; + next: TNode; + constructor(val: number, next: TNode = null){ + this.val = val; + this.next = next; + } +} +type TNode = ListNode | null; +*/ + +function linked_list_reversal_recursive(head: TNode): TNode { + // Base cases. + if (!head || !head.next) + return head; + // Recursively reverse the sublist starting from the next node. + const new_head: TNode = linked_list_reversal_recursive(head.next); + // Connect the reversed linked list to the head node to fully + // reverse the entire linked list. + head.next.next = head; + head.next = null; + return new_head; +} From 8a59277efc2c579131924683466854b4ba7b03ac Mon Sep 17 00:00:00 2001 From: aikhelis Date: Sat, 1 Feb 2025 15:00:28 +0000 Subject: [PATCH 02/27] ts-3: camelCase naming --- .../Linked Lists/linked_list_reversal.ts | 28 +++++++++---------- .../linked_list_reversal_recursive.ts | 12 ++++---- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/typescript/Linked Lists/linked_list_reversal.ts b/typescript/Linked Lists/linked_list_reversal.ts index 2c5d745..0febe62 100644 --- a/typescript/Linked Lists/linked_list_reversal.ts +++ b/typescript/Linked Lists/linked_list_reversal.ts @@ -1,27 +1,27 @@ // Definition of ListNode: class ListNode { val: number; - next: TNode; - constructor(val: number, next: TNode = null){ + next: LLNode; + constructor(val: number, next: LLNode = null){ this.val = val; this.next = next; } } -type TNode = ListNode | null; +type LLNode = ListNode | null; -function linked_list_reversal(head: TNode): TNode { - let curr_node: TNode = head; - let prev_node: TNode = null; - // Reverse the direction of each node's pointer until 'curr_node' +function linkedListReversal(head: LLNode): LLNode { + let currNode: LLNode = head; + let prevNode: LLNode = null; + // Reverse the direction of each node's pointer until 'currNode' // is null. - while (curr_node !== null){ - const next_node: TNode = curr_node.next; - curr_node.next = prev_node; - prev_node = curr_node; - curr_node = next_node; + while (currNode !== null){ + const nextNode: LLNode = currNode.next; + currNode.next = prevNode; + prevNode = currNode; + currNode = nextNode; } - // 'prev_node' will be pointing at the head of the reversed linked + // 'prevNode' will be pointing at the head of the reversed linked // list. - return prev_node; + return prevNode; } diff --git a/typescript/Linked Lists/linked_list_reversal_recursive.ts b/typescript/Linked Lists/linked_list_reversal_recursive.ts index 31ee834..4198840 100644 --- a/typescript/Linked Lists/linked_list_reversal_recursive.ts +++ b/typescript/Linked Lists/linked_list_reversal_recursive.ts @@ -1,24 +1,24 @@ /* Definition of ListNode: class ListNode { val: number; - next: TNode; - constructor(val: number, next: TNode = null){ + next: LLNode; + constructor(val: number, next: LLNode = null){ this.val = val; this.next = next; } } -type TNode = ListNode | null; +type LLNode = ListNode | null; */ -function linked_list_reversal_recursive(head: TNode): TNode { +function linkedListReversalRecursive(head: LLNode): LLNode { // Base cases. if (!head || !head.next) return head; // Recursively reverse the sublist starting from the next node. - const new_head: TNode = linked_list_reversal_recursive(head.next); + const newHead: LLNode = linkedListReversalRecursive(head.next); // Connect the reversed linked list to the head node to fully // reverse the entire linked list. head.next.next = head; head.next = null; - return new_head; + return newHead; } From 0bbb17781c7de97efaa95b72bd66194ca9cc47b0 Mon Sep 17 00:00:00 2001 From: aikhelis Date: Sat, 1 Feb 2025 20:37:19 +0000 Subject: [PATCH 03/27] ts-3: remove kth last node --- .../Linked Lists/remove_kth_last_node.ts | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 typescript/Linked Lists/remove_kth_last_node.ts diff --git a/typescript/Linked Lists/remove_kth_last_node.ts b/typescript/Linked Lists/remove_kth_last_node.ts new file mode 100644 index 0000000..4a9edaf --- /dev/null +++ b/typescript/Linked Lists/remove_kth_last_node.ts @@ -0,0 +1,38 @@ +/* Definition of ListNode: */ +// class ListNode { +// val: number; +// next: LLNode; +// constructor(val: number){ +// this.val = val; +// this.next = null; +// } +// } +// type LLNode = ListNode | null; + +function removeKthLastNode(head: LLNode, k: number): LLNode { + // If k is less than or equal to 0, no node needs to be removed. + if (k <= 0) + return head; + // A dummy node to ensure there's a node before 'head' in case we + // need to remove the head node. + let dummy: LLNode = new ListNode(-1); + dummy.next = head; + let trailer: LLNode = dummy, leader: LLNode = dummy; + // Advance 'leader' k steps ahead. + for (let i = 0; i < k; i++){ + leader = leader.next; + // If k is larger than the length of the linked list, no node + // needs to be removed. + if (leader === null) + return head; + } + // Move 'leader' to the end of the linked list, keeping 'trailer' + // k nodes behind. + while (leader.next !== null){ + leader = leader.next; + trailer = trailer.next; + } + // Remove the kth node from the end. + trailer.next = trailer.next.next; + return dummy.next; +} \ No newline at end of file From 22ca124ec225e6612580d148040d504b915da7a4 Mon Sep 17 00:00:00 2001 From: aikhelis Date: Sat, 1 Feb 2025 20:40:25 +0000 Subject: [PATCH 04/27] ts-3: commend node definition --- .../Linked Lists/linked_list_reversal.ts | 3 ++- .../Linked Lists/remove_kth_last_node.ts | 21 ++++++++++--------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/typescript/Linked Lists/linked_list_reversal.ts b/typescript/Linked Lists/linked_list_reversal.ts index 0febe62..323755e 100644 --- a/typescript/Linked Lists/linked_list_reversal.ts +++ b/typescript/Linked Lists/linked_list_reversal.ts @@ -1,4 +1,4 @@ -// Definition of ListNode: +/* Definition of ListNode: class ListNode { val: number; next: LLNode; @@ -8,6 +8,7 @@ class ListNode { } } type LLNode = ListNode | null; +*/ function linkedListReversal(head: LLNode): LLNode { let currNode: LLNode = head; diff --git a/typescript/Linked Lists/remove_kth_last_node.ts b/typescript/Linked Lists/remove_kth_last_node.ts index 4a9edaf..9228c87 100644 --- a/typescript/Linked Lists/remove_kth_last_node.ts +++ b/typescript/Linked Lists/remove_kth_last_node.ts @@ -1,13 +1,14 @@ -/* Definition of ListNode: */ -// class ListNode { -// val: number; -// next: LLNode; -// constructor(val: number){ -// this.val = val; -// this.next = null; -// } -// } -// type LLNode = ListNode | null; +/* Definition of ListNode: +class ListNode { + val: number; + next: LLNode; + constructor(val: number){ + this.val = val; + this.next = null; + } +} +type LLNode = ListNode | null; +*/ function removeKthLastNode(head: LLNode, k: number): LLNode { // If k is less than or equal to 0, no node needs to be removed. From 2401f25a2227156bdcd8187a7df3d5fdb2f4f6b3 Mon Sep 17 00:00:00 2001 From: aikhelis Date: Sat, 1 Feb 2025 21:42:39 +0000 Subject: [PATCH 05/27] ts-3: intersection --- .../Linked Lists/linked_list_intersection.ts | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 typescript/Linked Lists/linked_list_intersection.ts diff --git a/typescript/Linked Lists/linked_list_intersection.ts b/typescript/Linked Lists/linked_list_intersection.ts new file mode 100644 index 0000000..ab3ca68 --- /dev/null +++ b/typescript/Linked Lists/linked_list_intersection.ts @@ -0,0 +1,29 @@ +/* Definition of ListNode: +class ListNode { + val: number; + next: LLNode; + constructor(val: number, next: LLNode = null){ + this.val = val; + this.next = next; + } +} +type LLNode = ListNode | null; +*/ + +function linkedListIntersection(head_A: LLNode, head_B: LLNode): LLNode { + let ptr_A = head_A, ptr_B = head_B; + // Traverse through list A with 'ptr_A' and list B with 'ptr_B' + // until they meet. + while (ptr_A !== ptr_B) { + // Traverse list A -> list B by first traversing 'ptr_A' and + // then, upon reaching the end of list A, continue the + // traversal from the head of list B. + ptr_A = ptr_A !== null ? ptr_A.next : head_B; + // Simultaneously, traverse list B -> list A. + ptr_B = ptr_B !== null ? ptr_B.next : head_A; + } + // At this point, 'ptr_A' and 'ptr_B' either point to the + // intersection node or both are null if the lists do not + // intersect. Return either pointer. + return ptr_A; +} From e08e1a1f38b44c29b490a98d8ef949e3481fd3c6 Mon Sep 17 00:00:00 2001 From: aikhelis Date: Sat, 1 Feb 2025 22:01:15 +0000 Subject: [PATCH 06/27] ts-3: palindromic --- .../Linked Lists/palindromic_linked_list.ts | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 typescript/Linked Lists/palindromic_linked_list.ts diff --git a/typescript/Linked Lists/palindromic_linked_list.ts b/typescript/Linked Lists/palindromic_linked_list.ts new file mode 100644 index 0000000..3401527 --- /dev/null +++ b/typescript/Linked Lists/palindromic_linked_list.ts @@ -0,0 +1,52 @@ +/* Definition of ListNode: +class ListNode { + val: number; + next: LLNode; + constructor(val: number){ + this.val = val; + this.next = null; + } +} +type LLNode = ListNode | null; +*/ + +function palindromicLinkedList(head: LLNode): boolean { + // Find the middle of the linked list and then reverse the second half of the + // linked list starting at this midpoint. + const mid = findMiddle(head); + const secondHead = reverseList(mid); + // Compare the first half and the reversed second half of the list + let ptr1 = head, ptr2 = secondHead; + let res = true; + while (ptr2) { + if (ptr1.val !== ptr2.val) { + res = false; + } + ptr1 = ptr1.next, ptr2 = ptr2.next; + } + return res; +} + +// From the 'Reverse Linked List' problem. +function reverseList(head: LLNode): LLNode { + let prevNode: LLNode = null; + let currNode: LLNode = head; + while (currNode) { + const nextNode = currNode.next; + currNode.next = prevNode; + prevNode = currNode; + currNode = nextNode; + } + return prevNode; +} + +// From the 'Linked List Midpoint' problem. +function findMiddle(head: LLNode): LLNode { + let slow: LLNode = head; + let fast: LLNode = head; + while (fast && fast.next) { + slow = slow.next; + fast = fast.next.next; + } + return slow; +} From ac5cdd792471088e91962f4d02ca2c7fea63a18e Mon Sep 17 00:00:00 2001 From: Jer3myYu Date: Fri, 31 Jan 2025 20:02:23 -0500 Subject: [PATCH 07/27] add: InvertBinaryTreeRecursive and InvertBinaryTreeIterative --- java/Trees/InvertBinaryTreeIterative.java | 40 +++++++++++++++++++++++ java/Trees/InvertBinaryTreeRecursive.java | 30 +++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 java/Trees/InvertBinaryTreeIterative.java create mode 100644 java/Trees/InvertBinaryTreeRecursive.java diff --git a/java/Trees/InvertBinaryTreeIterative.java b/java/Trees/InvertBinaryTreeIterative.java new file mode 100644 index 0000000..2d9d6f9 --- /dev/null +++ b/java/Trees/InvertBinaryTreeIterative.java @@ -0,0 +1,40 @@ +import java.util.Stack; + +import DS.TreeNode; + +/* + // Definition of TreeNode: + class TreeNode { + public int val; + public TreeNode left; + public TreeNode right; + public TreeNode(int val) { + this.val = val; + } + } + */ + +public class InvertBinaryTreeIterative { + public TreeNode invertBinaryTreeIterative(TreeNode root) { + if (root == null) { + return null; + } + Stack stack = new Stack<>(); + stack.push(root); + while (!stack.isEmpty()) { + TreeNode node = stack.pop(); + // Swap the left and right subtrees of the current node. + TreeNode tmp = node.left; + node.left = node.right; + node.right = tmp; + // Push the left and right subtrees onto the stack. + if (node.left != null) { + stack.push(node.left); + } + if (node.right != null) { + stack.push(node.right); + } + } + return root; + } +} diff --git a/java/Trees/InvertBinaryTreeRecursive.java b/java/Trees/InvertBinaryTreeRecursive.java new file mode 100644 index 0000000..ad2bdb2 --- /dev/null +++ b/java/Trees/InvertBinaryTreeRecursive.java @@ -0,0 +1,30 @@ +import DS.TreeNode; + +/* + // Definition of TreeNode: + class TreeNode { + public int val; + public TreeNode left; + public TreeNode right; + public TreeNode(int val) { + this.val = val; + } + } + */ + +public class InvertBinaryTreeRecursive { + public TreeNode invertBinaryTreeRecursive(TreeNode root) { + // Base case: If the node is null, there's nothing to invert. + if (root == null) { + return root; + } + // Swap the left and right subtrees of the current node. + TreeNode tmp = root.left; + root.left = root.right; + root.right = tmp; + // Recursively invert the left and right subtrees. + invertBinaryTreeRecursive(root.left); + invertBinaryTreeRecursive(root.right); + return root; + } +} From 87309e4c48686ecd189f6ec90d9d0b81b1f6a988 Mon Sep 17 00:00:00 2001 From: Jer3myYu Date: Fri, 31 Jan 2025 20:07:36 -0500 Subject: [PATCH 08/27] add: BalancedBinaryTreeValidation --- java/Trees/BalancedBinaryTreeValidation.java | 40 ++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 java/Trees/BalancedBinaryTreeValidation.java diff --git a/java/Trees/BalancedBinaryTreeValidation.java b/java/Trees/BalancedBinaryTreeValidation.java new file mode 100644 index 0000000..ac4287c --- /dev/null +++ b/java/Trees/BalancedBinaryTreeValidation.java @@ -0,0 +1,40 @@ +import DS.TreeNode; + +/* + // Definition of TreeNode: + class TreeNode { + public int val; + public TreeNode left; + public TreeNode right; + public TreeNode(int val) { + this.val = val; + } + } + */ + +public class BalancedBinaryTreeValidation { + public boolean balancedBinaryTreeValidation(TreeNode root) { + return getHeightImbalance(root) != -1; + } + + private int getHeightImbalance(TreeNode node) { + // Base case: if the node is null, its height is 0. + if (node == null) { + return 0; + } + // Recursively get the height of the left and right subtrees. If + // either subtree is imbalanced, propagate -1 up the tree. + int leftHeight = getHeightImbalance(node.left); + int rightHeight = getHeightImbalance(node.right); + if (leftHeight == -1 || rightHeight == -1) { + return -1; + } + // If the current node's subtree is imbalanced + // (height difference > 1), return -1. + if (Math.abs(leftHeight - rightHeight) > 1) { + return -1; + } + // Return the height of the current subtree. + return 1 + Math.max(leftHeight, rightHeight); + } +} From cbf04e1b012dd0b78a342213c9138a55ad00ef14 Mon Sep 17 00:00:00 2001 From: Jer3myYu Date: Fri, 31 Jan 2025 20:20:23 -0500 Subject: [PATCH 09/27] add: RightmostNodesOfABinaryTree --- java/Trees/RightmostNodesOfABinaryTree.java | 48 +++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 java/Trees/RightmostNodesOfABinaryTree.java diff --git a/java/Trees/RightmostNodesOfABinaryTree.java b/java/Trees/RightmostNodesOfABinaryTree.java new file mode 100644 index 0000000..9fadf6e --- /dev/null +++ b/java/Trees/RightmostNodesOfABinaryTree.java @@ -0,0 +1,48 @@ +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.List; +import java.util.Queue; + +import DS.TreeNode; + +/* + // Definition of TreeNode: + class TreeNode { + public int val; + public TreeNode left; + public TreeNode right; + public TreeNode(int val) { + this.val = val; + } + } + */ + +public class RightmostNodesOfABinaryTree { + public List rightmostNodesOfABinaryTree(TreeNode root) { + if (root == null) { + return new ArrayList<>(); + } + List res = new ArrayList<>(); + Queue queue = new ArrayDeque<>(); + queue.offer(root); + while (!queue.isEmpty()) { + int levelSize = queue.size(); + // Add all the non-null child nodes of the current level to the + // queue. + for (int i = 0; i < levelSize; i++) { + TreeNode node = queue.poll(); + if (node.left != null) { + queue.offer(node.left); + } + if (node.right != null) { + queue.offer(node.right); + } + // Record this level's last node to the result array. + if (i == levelSize - 1) { + res.add(node.val); + } + } + } + return res; + } +} From 20c0102a9b3c84196c1fb94d84d63b76391285ae Mon Sep 17 00:00:00 2001 From: Jer3myYu Date: Fri, 31 Jan 2025 20:32:12 -0500 Subject: [PATCH 10/27] add: WidestBinaryTreeLevel --- java/Trees/WidestBinaryTreeLevel.java | 60 +++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 java/Trees/WidestBinaryTreeLevel.java diff --git a/java/Trees/WidestBinaryTreeLevel.java b/java/Trees/WidestBinaryTreeLevel.java new file mode 100644 index 0000000..8ab0225 --- /dev/null +++ b/java/Trees/WidestBinaryTreeLevel.java @@ -0,0 +1,60 @@ +import java.util.ArrayDeque; +import java.util.Queue; + +import DS.TreeNode; + +/* + // Definition of TreeNode: + class TreeNode { + public int val; + public TreeNode left; + public TreeNode right; + public TreeNode(int val) { + this.val = val; + } + } + */ + +public class WidestBinaryTreeLevel { + public class Pair { + TreeNode node; + int index; + public Pair(TreeNode node, int index) { + this.node = node; + this.index = index; + } + } + + public int widestBinaryTreeLevel(TreeNode root) { + if (root == null) { + return 0; + } + int maxWidth = 0; + Queue queue = new ArrayDeque<>(); + queue.offer(new Pair(root, 0)); // Stores (node, index) pairs. + while (!queue.isEmpty()) { + int levelSize = queue.size(); + // Set the 'leftmostIndex' to the index of the first node in + // this level. Start 'rightmostIndex' at the same point as + // 'leftmostIndex' and update it as we traverse the level, + // eventually positioning it at the last node. + int leftmostIndex = queue.peek().index; + int rightmostIndex = leftmostIndex; + // Process all nodes at the current level. + for (int j = 0; j < levelSize; j++) { + Pair pair = queue.poll(); + TreeNode node = pair.node; + int i = pair.index; + if (node.left != null) { + queue.offer(new Pair(node.left, 2 * i + 1)); + } + if (node.right != null) { + queue.offer(new Pair(node.right, 2 * i + 2)); + } + rightmostIndex = i; + } + maxWidth = Math.max(maxWidth, rightmostIndex - leftmostIndex + 1); + } + return maxWidth; + } +} From 92d90ef9f3b606c62f01d5924f70e2c811809150 Mon Sep 17 00:00:00 2001 From: Jer3myYu Date: Fri, 31 Jan 2025 20:45:29 -0500 Subject: [PATCH 11/27] add: BinarySearchTreeValidation, use null to replace float('-inf') and float('inf') in python solution --- java/Trees/BinarySearchTreeValidation.java | 39 ++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 java/Trees/BinarySearchTreeValidation.java diff --git a/java/Trees/BinarySearchTreeValidation.java b/java/Trees/BinarySearchTreeValidation.java new file mode 100644 index 0000000..3aab5ed --- /dev/null +++ b/java/Trees/BinarySearchTreeValidation.java @@ -0,0 +1,39 @@ +import DS.TreeNode; + +/* + // Definition of TreeNode: + class TreeNode { + public int val; + public TreeNode left; + public TreeNode right; + public TreeNode(int val) { + this.val = val; + } + } + */ + +public class BinarySearchTreeValidation { + public boolean binarySearchTreeValidation(TreeNode root) { + // Start validation at the root node. The root node can contain any + // value, so set the initial lower and upper bounds to null. + return isWithinBounds(root, null, null); + } + + private boolean isWithinBounds(TreeNode node, Integer lowerBound, Integer upperBound) { + // Base case: if the node is null, it satisfies the BST condition. + if (node == null) { + return true; + } + // If the current node's value is not within the valid bounds, this + // tree is not a valid BST. + if (lowerBound != null && node.val <= lowerBound || upperBound != null && upperBound <= node.val) { + return false; + } + // If the left subtree isn't a BST, this tree isn't a BST. + if (!isWithinBounds(node.left, lowerBound, node.val)) { + return false; + } + // Otherwise, return true if the right subtree is also a BST. + return isWithinBounds(node.right, node.val, upperBound); + } +} From 13e7aefab6b549107609f4cfc600923bcc50546e Mon Sep 17 00:00:00 2001 From: Jer3myYu Date: Fri, 31 Jan 2025 21:06:32 -0500 Subject: [PATCH 12/27] add: LowestCommonAncestor --- java/Trees/LowestCommonAncestor.java | 41 ++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 java/Trees/LowestCommonAncestor.java diff --git a/java/Trees/LowestCommonAncestor.java b/java/Trees/LowestCommonAncestor.java new file mode 100644 index 0000000..65b5b56 --- /dev/null +++ b/java/Trees/LowestCommonAncestor.java @@ -0,0 +1,41 @@ +import DS.TreeNode; + +/* + // Definition of TreeNode: + class TreeNode { + public int val; + public TreeNode left; + public TreeNode right; + public TreeNode(int val) { + this.val = val; + } + } + */ + +public class LowestCommonAncestor { + TreeNode lca; + + public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + dfs(root, p, q); + return lca; + } + + private boolean dfs(TreeNode node, TreeNode p, TreeNode q) { + // Base case: a null node is neither 'p' nor 'q'. + if (node == null) { + return false; + } + int nodeIsPOrQ = (node == p || node == q) ? 1 : 0; + // Recursively determine if the left and right subtrees contain 'p' + // or 'q'. + int leftContainsPOrQ = dfs(node.left, p, q) ? 1 : 0; + int rightContainsPOrQ = dfs(node.right, p, q) ? 1 : 0; + // If two of the above three variables are true, the current node is + // the LCA. + if (nodeIsPOrQ + leftContainsPOrQ + rightContainsPOrQ == 2) { + lca = node; + } + // Return true if the current subtree contains 'p' or 'q'. + return nodeIsPOrQ + leftContainsPOrQ + rightContainsPOrQ > 0; + } +} From 54a8a98adab4d93732ef85e020e48f2202311fcc Mon Sep 17 00:00:00 2001 From: Jer3myYu Date: Fri, 31 Jan 2025 21:23:57 -0500 Subject: [PATCH 13/27] add: BuildBinaryTree --- java/Trees/BuildBinaryTree.java | 50 +++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 java/Trees/BuildBinaryTree.java diff --git a/java/Trees/BuildBinaryTree.java b/java/Trees/BuildBinaryTree.java new file mode 100644 index 0000000..d25af53 --- /dev/null +++ b/java/Trees/BuildBinaryTree.java @@ -0,0 +1,50 @@ +import java.util.HashMap; +import java.util.Map; + +import DS.TreeNode; + +/* + // Definition of TreeNode: + class TreeNode { + public int val; + public TreeNode left; + public TreeNode right; + public TreeNode(int val) { + this.val = val; + } + } + */ + +public class BuildBinaryTree { + int preorderIndex = 0; + Map inorderIndexesMap = new HashMap<>(); + + public TreeNode buildBinaryTree(int[] preorder, int[] inorder) { + // Populate the hash map with the inorder values and their indexes. + for (int i = 0; i < inorder.length; i++) { + inorderIndexesMap.put(inorder[i], i); + } + // Build the tree and return its root node. + return buildSubtree(0, inorder.length - 1, preorder, inorder); + } + + private TreeNode buildSubtree(int left, int right, int[] preorder, int[] inorder) { + // Base case: if no elements are in this range, return None. + if (left > right) { + return null; + } + int val = preorder[preorderIndex]; + // Set 'inorderIndex' to the index of the same value pointed at by + // 'preorderIndex'. + int inorderIndex = inorderIndexesMap.get(val); + TreeNode node = new TreeNode(val); + // Advance 'preorderIndex' so it points to the value of the next + // node to be created. + preorderIndex++; + // Build the left and right subtrees and connect them to the current + // node. + node.left = buildSubtree(left, inorderIndex - 1, preorder, inorder); + node.right = buildSubtree(inorderIndex + 1, right, preorder, inorder); + return node; + } +} From c92cbf933b1eac441fc1c4ea7692d06ce2e91139 Mon Sep 17 00:00:00 2001 From: Jer3myYu Date: Fri, 31 Jan 2025 21:30:35 -0500 Subject: [PATCH 14/27] add: MaximumPathSum --- java/Trees/MaximumPathSum.java | 39 ++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 java/Trees/MaximumPathSum.java diff --git a/java/Trees/MaximumPathSum.java b/java/Trees/MaximumPathSum.java new file mode 100644 index 0000000..e9fd0a7 --- /dev/null +++ b/java/Trees/MaximumPathSum.java @@ -0,0 +1,39 @@ +import DS.TreeNode; + +/* + // Definition of TreeNode: + class TreeNode { + public int val; + public TreeNode left; + public TreeNode right; + public TreeNode(int val) { + this.val = val; + } + } + */ + +public class MaximumPathSum { + int maxSum = Integer.MIN_VALUE; + + public int maxPathSum(TreeNode root) { + maxPathSumHelper(root); + return maxSum; + } + + private int maxPathSumHelper(TreeNode node) { + // Base case: null nodes have no path sum. + if (node == null) { + return 0; + } + // Collect the maximum gain we can attain from the left and right + // subtrees, setting them to 0 if they're negative. + int leftSum = Math.max(maxPathSumHelper(node.left), 0); + int rightSum = Math.max(maxPathSumHelper(node.right), 0); + // Update the overall maximum path sum if the current path sum is + // larger. + maxSum = Math.max(maxSum, node.val + leftSum + rightSum); + // Return the maximum sum of a single, continuous path with the + // current node as an endpoint. + return node.val + Math.max(leftSum, rightSum); + } +} From 8ae766cc7e65be465fee50c1828da025a0bd28f9 Mon Sep 17 00:00:00 2001 From: Jer3myYu Date: Fri, 31 Jan 2025 21:36:31 -0500 Subject: [PATCH 15/27] add: BinaryTreeSymmetry --- java/Trees/BinaryTreeSymmetry.java | 44 ++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 java/Trees/BinaryTreeSymmetry.java diff --git a/java/Trees/BinaryTreeSymmetry.java b/java/Trees/BinaryTreeSymmetry.java new file mode 100644 index 0000000..75ca523 --- /dev/null +++ b/java/Trees/BinaryTreeSymmetry.java @@ -0,0 +1,44 @@ +import DS.TreeNode; + +/* + // Definition of TreeNode: + class TreeNode { + public int val; + public TreeNode left; + public TreeNode right; + public TreeNode(int val) { + this.val = val; + } + } + */ + +public class BinaryTreeSymmetry { + public boolean binaryTreeSymmetry(TreeNode root) { + if (root == null) { + return true; + } + return compareTrees(root.left, root.right); + } + + private boolean compareTrees(TreeNode node1, TreeNode node2) { + // Base case: if both nodes are null, they're symmetric. + if (node1 == null && node2 == null) { + return true; + } + // If one node is null and the other isn't, they aren't symmetric. + if (node1 == null || node2 == null) { + return false; + } + // If the values of the current nodes don't match, trees aren't symmetric. + if (node1.val != node2.val) { + return false; + } + // Compare the 'node1's left subtree with 'node2's right subtree. If these + // aren't symmetric, the whole tree is not symmetric. + if (!compareTrees(node1.left, node2.right)) { + return false; + } + // Compare the 'node1's right subtree with 'node2's left subtree. + return compareTrees(node1.right, node2.left); + } +} From e2a249976932c13c70488a74bf9537eaeeb6541e Mon Sep 17 00:00:00 2001 From: Jer3myYu Date: Fri, 31 Jan 2025 22:02:11 -0500 Subject: [PATCH 16/27] add: BinaryTreeColumns --- java/Trees/BinaryTreeColumns.java | 68 +++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 java/Trees/BinaryTreeColumns.java diff --git a/java/Trees/BinaryTreeColumns.java b/java/Trees/BinaryTreeColumns.java new file mode 100644 index 0000000..f22dbc6 --- /dev/null +++ b/java/Trees/BinaryTreeColumns.java @@ -0,0 +1,68 @@ +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Queue; + +import DS.TreeNode; + +/* + // Definition of TreeNode: + class TreeNode { + public int val; + public TreeNode left; + public TreeNode right; + public TreeNode(int val) { + this.val = val; + } + } + */ + +public class BinaryTreeColumns { + public class Pair { + TreeNode node; + int column; + public Pair(TreeNode node, int column) { + this.node = node; + this.column = column; + } + } + + public List> binaryTreeColumns(TreeNode root) { + if (root == null) { + return new ArrayList<>(); + } + Map> columnMap = new HashMap<>(); + int leftmostColumn, rightmostColumn; + leftmostColumn = rightmostColumn = 0; + Queue queue = new ArrayDeque<>(); + queue.offer(new Pair(root, 0)); + while (!queue.isEmpty()) { + Pair pair = queue.poll(); + TreeNode node = pair.node; + int column = pair.column; + if (node != null) { + // Add the current node's value to its corresponding list in the hash + // map. + List columnList = columnMap.getOrDefault(column, new ArrayList<>()); + columnList.add(node.val); + columnMap.put(column, columnList); + leftmostColumn = Math.min(leftmostColumn, column); + rightmostColumn = Math.max(rightmostColumn, column); + // Add the current node's children to the queue with their respective + // column ids. + queue.offer(new Pair(node.left, column - 1)); + queue.offer(new Pair(node.right, column + 1)); + } + } + // Construct the output list by collecting values from each column in the hash + // map in the correct order. + List> res = new ArrayList<>(); + for (int i = leftmostColumn; i <= rightmostColumn; i++) { + List column = columnMap.get(i); + res.add(column); + } + return res; + } +} From a2896659e03717c0a92c0306759a43666ef162b2 Mon Sep 17 00:00:00 2001 From: Jer3myYu Date: Fri, 31 Jan 2025 22:09:19 -0500 Subject: [PATCH 17/27] add: KthSmallestNumberInBSTRecursive --- .../KthSmallestNumberInBSTRecursive.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 java/Trees/KthSmallestNumberInBSTRecursive.java diff --git a/java/Trees/KthSmallestNumberInBSTRecursive.java b/java/Trees/KthSmallestNumberInBSTRecursive.java new file mode 100644 index 0000000..dbead79 --- /dev/null +++ b/java/Trees/KthSmallestNumberInBSTRecursive.java @@ -0,0 +1,34 @@ +import java.util.ArrayList; +import java.util.List; + +import DS.TreeNode; + +/* + // Definition of TreeNode: + class TreeNode { + public int val; + public TreeNode left; + public TreeNode right; + public TreeNode(int val) { + this.val = val; + } + } + */ + +public class KthSmallestNumberInBSTRecursive { + public int kthSmallestNumberInBSTRecursive(TreeNode root, int k) { + List sortedList = new ArrayList<>(); + inorder(root, sortedList); + return sortedList.get(k - 1); + } + + // Inorder traversal function to attain a sorted list of nodes from the BST. + private void inorder(TreeNode node, List sortedList) { + if (node == null) { + return; + } + inorder(node.left, sortedList); + sortedList.add(node.val); + inorder(node.right, sortedList); + } +} From 0c05a1e302aea37ce96c59ecbb1876f0e57b8d3e Mon Sep 17 00:00:00 2001 From: Jer3myYu Date: Fri, 31 Jan 2025 22:15:48 -0500 Subject: [PATCH 18/27] add: KthSmallestNumberInBSTIterative --- .../KthSmallestNumberInBSTIterative.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 java/Trees/KthSmallestNumberInBSTIterative.java diff --git a/java/Trees/KthSmallestNumberInBSTIterative.java b/java/Trees/KthSmallestNumberInBSTIterative.java new file mode 100644 index 0000000..c9f4db0 --- /dev/null +++ b/java/Trees/KthSmallestNumberInBSTIterative.java @@ -0,0 +1,41 @@ +import java.util.Stack; + +import DS.TreeNode; + +/* + // Definition of TreeNode: + class TreeNode { + public int val; + public TreeNode left; + public TreeNode right; + public TreeNode(int val) { + this.val = val; + } + } + */ + +public class KthSmallestNumberInBSTIterative { + public int kthSmallestNumberInBSTIterative(TreeNode root, int k) { + Stack stack = new Stack<>(); + TreeNode node = root; + while (!stack.isEmpty() || node != null) { + // Move to the leftmost node and add nodes to the stack as we go so they + // can be processed in future iterations. + while (node != null) { + stack.push(node); + node = node.left; + } + // Pop the top node from the stack to process it, and decrement 'k'. + node = stack.pop(); + k--; + // If we have processed 'k' nodes, return the value of the 'k'th smallest + // node. + if (k == 0) { + return node.val; + } + // Move to the right subtree. + node = node.right; + } + return -1; + } +} From 5ba42cae8c22f7009ebac3d7c4b2a84d70050261 Mon Sep 17 00:00:00 2001 From: Jer3myYu Date: Fri, 31 Jan 2025 22:52:37 -0500 Subject: [PATCH 19/27] add: SerializeAndDeserializeABinaryTree --- .../SerializeAndDeserializeABinaryTree.java | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 java/Trees/SerializeAndDeserializeABinaryTree.java diff --git a/java/Trees/SerializeAndDeserializeABinaryTree.java b/java/Trees/SerializeAndDeserializeABinaryTree.java new file mode 100644 index 0000000..4e59fd6 --- /dev/null +++ b/java/Trees/SerializeAndDeserializeABinaryTree.java @@ -0,0 +1,64 @@ +import java.lang.StringBuilder; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.Queue; + +import DS.TreeNode; + +/* + // Definition of TreeNode: + class TreeNode { + public int val; + public TreeNode left; + public TreeNode right; + public TreeNode(int val) { + this.val = val; + } + } + */ + +public class SerializeAndDeserializeABinaryTree { + public String serialize(TreeNode root) { + // Perform a preorder traversal to add node values to a list, then convert the + // list to a string. + StringBuilder serializedList = new StringBuilder(); + preorderSerialize(root, serializedList); + return serializedList.toString(); + } + + // Helper function to perform serialization through preorder traversal. + private void preorderSerialize(TreeNode node, StringBuilder serializedList) { + // Base case: mark null nodes as '#'. + if (node == null) { + serializedList.append("#").append(","); + return; + } + // Preorder traversal processes the current node first, then the left and right + // children. + serializedList.append(node.val).append(","); + preorderSerialize(node.left, serializedList); + preorderSerialize(node.right, serializedList); + } + + public TreeNode deserialize(String data) { + // Obtain the node values by splitting the string using the comma delimiter. + Queue nodeValues = new LinkedList<>(); + nodeValues.addAll(Arrays.asList(data.split(","))); + return buildTree(nodeValues); + } + + // Helper function to construct the tree using preorder traversal. + private TreeNode buildTree(Queue values) { + String val = values.poll(); + // Base case: '#' indicates a null node. + if (val.equals("#")) { + return null; + } + // Use preorder traversal processes the current node first, then the left and + // right children. + TreeNode node = new TreeNode(Integer.valueOf(val)); + node.left = buildTree(values); + node.right = buildTree(values); + return node; + } +} From dc941b6927312c4db2d7382a341a6e5402412f21 Mon Sep 17 00:00:00 2001 From: aikhelis Date: Sat, 1 Feb 2025 14:27:38 +0000 Subject: [PATCH 20/27] ts-1 ts-2: naming aligned with language standard --- .../geometric_sequence_triplets.ts | 20 +++++------ .../longest_chain_of_consecutive_numbers.ts | 16 ++++----- ...hain_of_consecutive_numbers_brute_force.ts | 18 +++++----- .../Hash Maps and Sets/pair_sum_unsorted.ts | 12 +++---- .../pair_sum_unsorted_two_pass.ts | 14 ++++---- .../Hash Maps and Sets/verify_sudoku_board.ts | 20 +++++------ .../Hash Maps and Sets/zero_striping.ts | 14 ++++---- .../zero_striping_hash_sets.ts | 12 +++---- .../Two Pointers/is_palindrome_valid.ts | 22 ++++++------ typescript/Two Pointers/largest_container.ts | 18 +++++----- .../largest_container_brute_force.ts | 12 +++---- .../next_lexicographical_sequence.ts | 14 ++++---- typescript/Two Pointers/pair_sum_sorted.ts | 14 ++++---- .../pair_sum_sorted_brute_force.ts | 6 ++-- .../Two Pointers/shift_zeros_to_the_end.ts | 8 ++--- .../shift_zeros_to_the_end_naive.ts | 12 +++---- typescript/Two Pointers/triplet_sum.ts | 36 +++++++++---------- .../Two Pointers/triplet_sum_brute_force.ts | 8 ++--- 18 files changed, 138 insertions(+), 138 deletions(-) diff --git a/typescript/Hash Maps and Sets/geometric_sequence_triplets.ts b/typescript/Hash Maps and Sets/geometric_sequence_triplets.ts index aa8ede8..7725a28 100644 --- a/typescript/Hash Maps and Sets/geometric_sequence_triplets.ts +++ b/typescript/Hash Maps and Sets/geometric_sequence_triplets.ts @@ -1,20 +1,20 @@ -function geometric_sequence_triplets(nums: number[], r: number): number { - const left_map: { [key: number]: number } = {}; - const right_map: { [key: number]: number } = {}; +function geometricSequenceTriplets(nums: number[], r: number): number { + const leftMap: { [key: number]: number } = {}; + const rightMap: { [key: number]: number } = {}; let count = 0; - // Populate 'right_map' with the frequency of each element in the array. + // Populate 'rightMap' with the frequency of each element in the array. for (const x of nums) - right_map[x] = (right_map[x] ?? 0) + 1; + rightMap[x] = (rightMap[x] ?? 0) + 1; // Search for geometric triplets that have x as the center. for (const x of nums) { - // Decrement the frequency of x in right_map since x is now being + // Decrement the frequency of x in rightMap since x is now being // processed and is no longer to the right. - right_map[x] -= 1; + rightMap[x] -= 1; if (x % r === 0) - count += (left_map[x / r] ?? 0) * (right_map[x * r] ?? 0); - // Increment the frequency of x in left_map since it'll be a part of the + count += (leftMap[x / r] ?? 0) * (rightMap[x * r] ?? 0); + // Increment the frequency of x in leftMap since it'll be a part of the // left side of the array once we iterate to the next value of x. - left_map[x] = (left_map[x] ?? 0) + 1; + leftMap[x] = (leftMap[x] ?? 0) + 1; } return count; } \ No newline at end of file diff --git a/typescript/Hash Maps and Sets/longest_chain_of_consecutive_numbers.ts b/typescript/Hash Maps and Sets/longest_chain_of_consecutive_numbers.ts index e015097..f57b076 100644 --- a/typescript/Hash Maps and Sets/longest_chain_of_consecutive_numbers.ts +++ b/typescript/Hash Maps and Sets/longest_chain_of_consecutive_numbers.ts @@ -1,21 +1,21 @@ -function longest_chain_of_consecutive_numbers(nums: number[]): number { +function longestChainOfConsecutiveNumbers(nums: number[]): number { if (nums.length === 0) return 0; - const num_set = new Set(nums); - let longest_chain = 0; - for (const num of num_set) { + const numSet = new Set(nums); + let longestChain = 0; + for (const num of numSet) { // If the current number is the smallest number in its chain, search for // the length of its chain. - if (!num_set.has(num - 1)) { + if (!numSet.has(num - 1)) { let currentNum = num; let currentChain = 1; // Continue to find the next consecutive numbers in the chain. - while (num_set.has(currentNum + 1)) { + while (numSet.has(currentNum + 1)) { currentNum += 1; currentChain += 1; } - longest_chain = Math.max(longest_chain, currentChain); + longestChain = Math.max(longestChain, currentChain); } } - return longest_chain; + return longestChain; } \ No newline at end of file diff --git a/typescript/Hash Maps and Sets/longest_chain_of_consecutive_numbers_brute_force.ts b/typescript/Hash Maps and Sets/longest_chain_of_consecutive_numbers_brute_force.ts index fbb8efe..ac4ca9d 100644 --- a/typescript/Hash Maps and Sets/longest_chain_of_consecutive_numbers_brute_force.ts +++ b/typescript/Hash Maps and Sets/longest_chain_of_consecutive_numbers_brute_force.ts @@ -1,17 +1,17 @@ -function longest_chain_of_consecutive_numbers_brute_force(nums: number[]): number { +function longestChainOfConsecutiveNumbersBruteForce(nums: number[]): number { if (nums.length === 0) return 0; - let longest_chain = 0; + let longestChain = 0; // Look for chains of consecutive numbers that start from each number. for (const num of nums) { - let current_num = num; - let current_chain = 1; + let currentNum = num; + let currentChain = 1; // Continue to find the next consecutive numbers in the chain. - while (nums.includes(current_num + 1)) { - current_num += 1; - current_chain += 1; + while (nums.includes(currentNum + 1)) { + currentNum += 1; + currentChain += 1; } - longest_chain = Math.max(longest_chain, current_chain); + longestChain = Math.max(longestChain, currentChain); } - return longest_chain; + return longestChain; } \ No newline at end of file diff --git a/typescript/Hash Maps and Sets/pair_sum_unsorted.ts b/typescript/Hash Maps and Sets/pair_sum_unsorted.ts index 7fbbeb3..8fcaeb5 100644 --- a/typescript/Hash Maps and Sets/pair_sum_unsorted.ts +++ b/typescript/Hash Maps and Sets/pair_sum_unsorted.ts @@ -1,9 +1,9 @@ -function pair_sum_unsorted(nums: number[], target: number): number[] { - const hashmap = {} +function pairSumUnsorted(nums: number[], target: number): number[] { + const hashMap: { [key: number]: number } = {}; for (let i = 0; i < nums.length; i++) { - if (hashmap[target - nums[i]] !== undefined) - return [hashmap[target - nums[i]], i] - hashmap[nums[i]] = i + if (hashMap[target - nums[i]] !== undefined) + return [hashMap[target - nums[i]], i]; + hashMap[nums[i]] = i; } - return [] + return []; } diff --git a/typescript/Hash Maps and Sets/pair_sum_unsorted_two_pass.ts b/typescript/Hash Maps and Sets/pair_sum_unsorted_two_pass.ts index ec36b9d..b4edd4c 100644 --- a/typescript/Hash Maps and Sets/pair_sum_unsorted_two_pass.ts +++ b/typescript/Hash Maps and Sets/pair_sum_unsorted_two_pass.ts @@ -1,14 +1,14 @@ -function pair_sum_unsorted_two_pass(nums: number[], target: number): number[] { - const num_map = {} +function pairSumUnsortedTwoPass(nums: number[], target: number): number[] { + const numMap: { [key: number]: number } = {}; // First pass: Populate the hash map with each number and its // index. for (let i = 0; i < nums.length; i++) - num_map[nums[i]] = i + numMap[nums[i]] = i; // Second pass: Check for each number's complement in the hash map. for (let i = 0; i < nums.length; i++) { - const complement = target - nums[i] - if (num_map[complement] !== undefined && num_map[complement] !== i) - return [i, num_map[complement]] + const complement = target - nums[i]; + if (numMap[complement] !== undefined && numMap[complement] !== i) + return [i, numMap[complement]]; } - return [] + return []; } diff --git a/typescript/Hash Maps and Sets/verify_sudoku_board.ts b/typescript/Hash Maps and Sets/verify_sudoku_board.ts index 4f1dca7..bbcd5f8 100644 --- a/typescript/Hash Maps and Sets/verify_sudoku_board.ts +++ b/typescript/Hash Maps and Sets/verify_sudoku_board.ts @@ -1,10 +1,10 @@ -function verify_sudoku_board(board: number[][]): boolean { +function verifySudokuBoard(board: number[][]): boolean { // Create hash sets for each row, column, and subgrid to keep // track of numbers previously seen on any given row, column, or // subgrid. - const row_sets: Set[] = Array.from({ length: 9 }, () => new Set()); - const column_sets: Set[] = Array.from({ length: 9 }, () => new Set()); - const subgrid_sets: Set[][] = Array.from({ length: 3 }, () => Array.from({ length: 3 }, () => new Set())); + const rowSets: Set[] = Array.from({ length: 9 }, () => new Set()); + const columnSets: Set[] = Array.from({ length: 9 }, () => new Set()); + const subgridSets: Set[][] = Array.from({ length: 3 }, () => Array.from({ length: 3 }, () => new Set())); for (let r = 0; r < 9; r++) { for (let c = 0; c < 9; c++) { const num = board[r][c]; @@ -12,17 +12,17 @@ function verify_sudoku_board(board: number[][]): boolean { continue; // Check if 'num' has been seen in the current row, // column, or subgrid. - if (row_sets[r].has(num)) + if (rowSets[r].has(num)) return false; - if (column_sets[c].has(num)) + if (columnSets[c].has(num)) return false; - if (subgrid_sets[Math.floor(r / 3)][Math.floor(c / 3)].has(num)) + if (subgridSets[Math.floor(r / 3)][Math.floor(c / 3)].has(num)) return false; // If we passed the above checks, mark this value as seen // by adding it to its corresponding hash sets. - row_sets[r].add(num); - column_sets[c].add(num); - subgrid_sets[Math.floor(r / 3)][Math.floor(c / 3)].add(num); + rowSets[r].add(num); + columnSets[c].add(num); + subgridSets[Math.floor(r / 3)][Math.floor(c / 3)].add(num); } } return true; diff --git a/typescript/Hash Maps and Sets/zero_striping.ts b/typescript/Hash Maps and Sets/zero_striping.ts index ac92317..79f86b8 100644 --- a/typescript/Hash Maps and Sets/zero_striping.ts +++ b/typescript/Hash Maps and Sets/zero_striping.ts @@ -1,20 +1,20 @@ -function zero_striping(matrix: number[][]): void { +function zeroStriping(matrix: number[][]): void { if (!matrix || !matrix[0]) return; const m = matrix.length, n = matrix[0].length; // Check if the first row initially contains a zero. - let first_row_has_zero = false; + let firstRowHasZero = false; for (let c = 0; c < n; c++) { if (matrix[0][c] === 0) { - first_row_has_zero = true; + firstRowHasZero = true; break; } } // Check if the first column initially contains a zero. - let first_col_has_zero = false; + let firstColHasZero = false; for (let r = 0; r < m; r++) { if (matrix[r][0] === 0) { - first_col_has_zero = true; + firstColHasZero = true; break; } } @@ -40,14 +40,14 @@ function zero_striping(matrix: number[][]): void { } // If the first row had a zero initially, set all elements in the // first row to zero. - if (first_row_has_zero) { + if (firstRowHasZero) { for (let c = 0; c < n; c++) { matrix[0][c] = 0; } } // If the first column had a zero initially, set all elements in // the first column to zero. - if (first_col_has_zero) { + if (firstColHasZero) { for (let r = 0; r < m; r++) { matrix[r][0] = 0; } diff --git a/typescript/Hash Maps and Sets/zero_striping_hash_sets.ts b/typescript/Hash Maps and Sets/zero_striping_hash_sets.ts index dde4523..9350e55 100644 --- a/typescript/Hash Maps and Sets/zero_striping_hash_sets.ts +++ b/typescript/Hash Maps and Sets/zero_striping_hash_sets.ts @@ -1,24 +1,24 @@ -function zero_striping_hash_sets(matrix: number[][]): void { +function zeroStripingHashSets(matrix: number[][]): void { if (!matrix || !matrix[0]) return; const m = matrix.length, n = matrix[0].length; - const zero_rows = new Set(), zero_cols = new Set(); + const zeroRows = new Set(), zeroCols = new Set(); // Pass 1: Traverse through the matrix to identify the rows and // columns containing zeros and store their indexes in the // appropriate hash sets. for (let r = 0; r < m; r++) { for (let c = 0; c < n; c++) { if (matrix[r][c] === 0) { - zero_rows.add(r); - zero_cols.add(c); + zeroRows.add(r); + zeroCols.add(c); } } } // Pass 2: Set any cell in the matrix to zero if its row index is - // in 'zero_rows' or its column index is in 'zero_cols'. + // in 'zeroRows' or its column index is in 'zeroCols'. for (let r = 0; r < m; r++) { for (let c = 0; c < n; c++) { - if (zero_rows.has(r) || zero_cols.has(c)) { + if (zeroRows.has(r) || zeroCols.has(c)) { matrix[r][c] = 0; } } diff --git a/typescript/Two Pointers/is_palindrome_valid.ts b/typescript/Two Pointers/is_palindrome_valid.ts index 4d33a5f..270d2b8 100644 --- a/typescript/Two Pointers/is_palindrome_valid.ts +++ b/typescript/Two Pointers/is_palindrome_valid.ts @@ -1,20 +1,20 @@ -function is_palindrome_valid(s: string): boolean { - let left = 0, right = s.length - 1 +function isPalindromeValid(s: string): boolean { + let left = 0, right = s.length - 1; while (left < right) { // Skip non-alphanumeric characters from the left. - while (left < right && !isalnum(s[left])) - left++ + while (left < right && !isAlphaNumeric(s[left])) + left++; // Skip non-alphanumeric characters from the right. - while (left < right && !isalnum(s[right])) - right-- + while (left < right && !isAlphaNumeric(s[right])) + right--; // If the characters at the left and right pointers don't // match, the string is not a palindrome. if (s[left] !== s[right]) - return false - left++ - right-- + return false; + left++; + right--; } - return true + return true; } -const isalnum = (c: string): boolean => /^[a-z0-9]+$/i.test(c); +const isAlphaNumeric = (c: string): boolean => /^[a-z0-9]+$/i.test(c); diff --git a/typescript/Two Pointers/largest_container.ts b/typescript/Two Pointers/largest_container.ts index 03bd298..86d4732 100644 --- a/typescript/Two Pointers/largest_container.ts +++ b/typescript/Two Pointers/largest_container.ts @@ -1,20 +1,20 @@ -function largest_container(heights: number[]): number { - let max_water = 0 - let left = 0, right = heights.length - 1 +function largestContainer(heights: number[]): number { + let maxWater = 0; + let left = 0, right = heights.length - 1; while (left < right) { // Calculate the water contained between the current pair of // lines. - let water = Math.min(heights[left], heights[right]) * (right - left) - max_water = Math.max(max_water, water) + let water = Math.min(heights[left], heights[right]) * (right - left); + maxWater = Math.max(maxWater, water); // Move the pointers inward, always moving the pointer at the // shorter line. If both lines have the same height, move both // pointers inward. if (heights[left] < heights[right]) - left++ + left++; else if (heights[left] > heights[right]) - right-- + right--; else - left++, right-- + left++, right--; } - return max_water + return maxWater; } diff --git a/typescript/Two Pointers/largest_container_brute_force.ts b/typescript/Two Pointers/largest_container_brute_force.ts index ab5d3ed..b1a8703 100644 --- a/typescript/Two Pointers/largest_container_brute_force.ts +++ b/typescript/Two Pointers/largest_container_brute_force.ts @@ -1,13 +1,13 @@ -function largest_container_brute_force(heights: number[]): number { - let n = heights.length - let max_water = 0 +function largestContainerBruteForce(heights: number[]): number { + let n = heights.length; + let maxWater = 0; // Find the maximum amount of water stored between all pairs of // lines. for (let i = 0; i < n - 1; i++) { for (let j = i + 1; j < n; j++) { - let water = Math.min(heights[i], heights[j]) * (j - i) - max_water = Math.max(max_water, water) + let water = Math.min(heights[i], heights[j]) * (j - i); + maxWater = Math.max(maxWater, water); } } - return max_water + return maxWater; } diff --git a/typescript/Two Pointers/next_lexicographical_sequence.ts b/typescript/Two Pointers/next_lexicographical_sequence.ts index 002474b..388f3c4 100644 --- a/typescript/Two Pointers/next_lexicographical_sequence.ts +++ b/typescript/Two Pointers/next_lexicographical_sequence.ts @@ -1,5 +1,5 @@ -function next_lexicographical_sequence(s: string): string { - let letters = [...s]; +function nextLexicographicalSequence(s: string): string { + let letters: string[] = [...s]; // Locate the pivot, which is the first character from the right that breaks // non-increasing order. Start searching from the second-to-last position. let pivot = letters.length - 2; @@ -10,14 +10,14 @@ function next_lexicographical_sequence(s: string): string { if (pivot === -1) return letters.reverse().join(''); // Find the rightmost successor to the pivot. - let rightmost_successor = letters.length - 1; - while (letters[rightmost_successor] <= letters[pivot]) - rightmost_successor--; + let rightmostSuccessor = letters.length - 1; + while (letters[rightmostSuccessor] <= letters[pivot]) + rightmostSuccessor--; // Swap the rightmost successor with the pivot to increase the lexicographical // order of the suffix. - [letters[pivot], letters[rightmost_successor]] = [letters[rightmost_successor], letters[pivot]]; + [letters[pivot], letters[rightmostSuccessor]] = [letters[rightmostSuccessor], letters[pivot]]; // Reverse the suffix after the pivot to minimize its permutation. const suffix = letters.slice(pivot + 1).reverse(); letters.splice(pivot + 1, suffix.length, ...suffix); return letters.join(''); -} +} diff --git a/typescript/Two Pointers/pair_sum_sorted.ts b/typescript/Two Pointers/pair_sum_sorted.ts index eabcd1d..d137243 100644 --- a/typescript/Two Pointers/pair_sum_sorted.ts +++ b/typescript/Two Pointers/pair_sum_sorted.ts @@ -1,18 +1,18 @@ -function pair_sum_sorted(nums: number[], target: number): number[] { - let left = 0, right = nums.length - 1 +function pairSumSorted(nums: number[], target: number): number[] { + let left = 0, right = nums.length - 1; while (left < right) { - let sum = nums[left] + nums[right] + let sum = nums[left] + nums[right]; // If the sum is smaller, increment the left pointer, aiming // to increase the sum toward the target value. if (sum < target) - left++ + left++; // If the sum is larger, decrement the right pointer, aiming // to decrease the sum toward the target value. else if (sum > target) - right-- + right--; // If the target pair is found, return its indexes. else - return [left, right] + return [left, right]; } - return [] + return []; } diff --git a/typescript/Two Pointers/pair_sum_sorted_brute_force.ts b/typescript/Two Pointers/pair_sum_sorted_brute_force.ts index 01eafe8..5006807 100644 --- a/typescript/Two Pointers/pair_sum_sorted_brute_force.ts +++ b/typescript/Two Pointers/pair_sum_sorted_brute_force.ts @@ -1,10 +1,10 @@ -function pair_sum_sorted_brute_force(nums: number[], target: number): number[] { +function pairSumSortedBruteForce(nums: number[], target: number): number[] { const n = nums.length; for (let i = 0; i < n; i++) { for (let j = i + 1; j < n; j++) { if (nums[i] + nums[j] === target) - return [i, j] + return [i, j]; } } - return [] + return []; } diff --git a/typescript/Two Pointers/shift_zeros_to_the_end.ts b/typescript/Two Pointers/shift_zeros_to_the_end.ts index f5d08c3..caf7c5e 100644 --- a/typescript/Two Pointers/shift_zeros_to_the_end.ts +++ b/typescript/Two Pointers/shift_zeros_to_the_end.ts @@ -1,14 +1,14 @@ -function shift_zeros_to_the_end(nums: number[]): void { +function shiftZerosToTheEnd(nums: number[]): void { // The 'left' pointer is used to position non-zero elements. - let left = 0 + let left = 0; // Iterate through the array using a 'right' pointer to locate non-zero // elements. for (let right = 0; right < nums.length; right++) { if (nums[right] !== 0) { - [nums[left], nums[right]] = [nums[right], nums[left]] + [nums[left], nums[right]] = [nums[right], nums[left]]; // Increment 'left' since it now points to a position already occupied // by a non-zero element. - left++ + left++; } } } diff --git a/typescript/Two Pointers/shift_zeros_to_the_end_naive.ts b/typescript/Two Pointers/shift_zeros_to_the_end_naive.ts index fde25b3..282002c 100644 --- a/typescript/Two Pointers/shift_zeros_to_the_end_naive.ts +++ b/typescript/Two Pointers/shift_zeros_to_the_end_naive.ts @@ -1,15 +1,15 @@ -function shift_zeros_to_the_end_naive(nums: number[]): void { - let temp = Array(nums.length).fill(0); - let i = 0 +function shiftZerosToTheEndNaive(nums: number[]): void { + let temp: number[] = Array(nums.length).fill(0); + let i = 0; // Add all non-zero elements to the left of 'temp'. for (let number of nums) { if (number !== 0) { - temp[i] = number - i++ + temp[i] = number; + i++; } } // Set 'nums' to 'temp'. for (let j = 0; j < nums.length; j++) { - nums[j] = temp[j] + nums[j] = temp[j]; } } diff --git a/typescript/Two Pointers/triplet_sum.ts b/typescript/Two Pointers/triplet_sum.ts index ad4c0f9..d009846 100644 --- a/typescript/Two Pointers/triplet_sum.ts +++ b/typescript/Two Pointers/triplet_sum.ts @@ -1,41 +1,41 @@ -function triplet_sum(nums: number[]): number[][] { - const triplets = [] - nums.sort() +function tripletSum(nums: number[]): number[][] { + const triplets: Array<[number, number, number]> = []; + nums.sort(); for (let i = 0; i < nums.length; i++) { // Optimization: triplets consisting of only positive numbers // will never sum to 0. if (nums[i] > 0 ) - break + break; // To avoid duplicate triplets, skip 'a' if it's the same as // the previous number. if (i > 0 && nums[i] === nums[i - 1]) - continue + continue; // Find all pairs that sum to a target of '-a' (-nums[i]). - const pairs = pair_sum_sorted_all_pairs(nums, i + 1, -nums[i]) + const pairs = pairSumSortedAllPairs(nums, i + 1, -nums[i]); for (const pair of pairs) { - triplets.push([nums[i]].concat(pair)) + triplets.push([nums[i], pair[0], pair[1]]); } } - return triplets + return triplets; } -function pair_sum_sorted_all_pairs(nums: number[], start: number, target: number): number[]{ - const pairs = [] - let left = start, right = nums.length - 1 +function pairSumSortedAllPairs(nums: number[], start: number, target: number): number[][] { + const pairs: Array<[number, number]> = []; + let left = start, right = nums.length - 1; while (left < right) { - const sum = nums[left] + nums[right] + const sum = nums[left] + nums[right]; if (sum === target) { - pairs.push([nums[left], nums[right]]) - left++ + pairs.push([nums[left], nums[right]]); + left++; // To avoid duplicate '[b, c]' pairs, skip 'b' if it's the // same as the previous number. while (left < right && nums[left] === nums[left - 1]) - left++ + left++; } else if (sum < target) { - left++ + left++; } else { - right-- + right--; } } - return pairs + return pairs; } diff --git a/typescript/Two Pointers/triplet_sum_brute_force.ts b/typescript/Two Pointers/triplet_sum_brute_force.ts index fb9dcfc..659a795 100644 --- a/typescript/Two Pointers/triplet_sum_brute_force.ts +++ b/typescript/Two Pointers/triplet_sum_brute_force.ts @@ -1,7 +1,7 @@ -function triplet_sum_brute_force(nums: number[]): number[][] { - let n = nums.length +function tripletSumBruteForce(nums: number[]): number[][] { + let n = nums.length; // Use a hash set to ensure we don't add duplicate triplets. - let triplets = new Set() + let triplets: Set = new Set(); // Iterate through the indexes of all triplets. for (let i = 0; i < n - 2; i++) { for (let j = i + 1; j < n - 1; j++) { @@ -16,5 +16,5 @@ function triplet_sum_brute_force(nums: number[]): number[][] { } } // [javascript] convert the Set back into an array of triplets. - return Array.from(triplets).map(JSON.parse) + return Array.from(triplets).map(JSON.parse); } From 539d2ed571c2651e564fc6332c1af79e0f98562e Mon Sep 17 00:00:00 2001 From: aikhelis Date: Sun, 2 Feb 2025 10:00:56 +0000 Subject: [PATCH 21/27] ts-3: flatten list --- .../Linked Lists/flatten_multi_level_list.ts | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 typescript/Linked Lists/flatten_multi_level_list.ts diff --git a/typescript/Linked Lists/flatten_multi_level_list.ts b/typescript/Linked Lists/flatten_multi_level_list.ts new file mode 100644 index 0000000..9cc5e1c --- /dev/null +++ b/typescript/Linked Lists/flatten_multi_level_list.ts @@ -0,0 +1,35 @@ +/* Definition of MultiLevelListNode: +class MultieLevelListNode { + val: number; next: MLLNode; child: MLLNode; + constructor(val: number){ + this.val = val; + this.next = null; + this.child = null; + } +} +type MLLNode = MultieLevelListNode | null; +*/ + +function flattenMultiLevelList(head: MLLNode): MLLNode { + if (!head) + return head; + let tail: MLLNode = head; + // Find the tail of the linked list at the first level. + while (tail.next !== null) + tail = tail.next; + let curr: MLLNode = head; + // Process each node at the current level. If a node has a child linked list, + // append it to the tail and then update the tail to the end of the extended + // linked list. Continue until all nodes at the current level are processed. + while (curr !== null){ + if (curr.child !== null){ + tail.next = curr.child; + // Disconnect the child linked list from the current node. + curr.child = null; + while (tail.next !== null) + tail = tail.next; + } + curr = curr.next; + } + return head; +} \ No newline at end of file From e6a13e9a86d0a61d73c6a667e142bfaee50270ac Mon Sep 17 00:00:00 2001 From: aikhelis Date: Sun, 2 Feb 2025 10:31:31 +0000 Subject: [PATCH 22/27] ts-3: align remove-kth-last-node with canonical solution with assumed constraints on input --- typescript/Linked Lists/remove_kth_last_node.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/typescript/Linked Lists/remove_kth_last_node.ts b/typescript/Linked Lists/remove_kth_last_node.ts index 9228c87..2e2d942 100644 --- a/typescript/Linked Lists/remove_kth_last_node.ts +++ b/typescript/Linked Lists/remove_kth_last_node.ts @@ -11,9 +11,6 @@ type LLNode = ListNode | null; */ function removeKthLastNode(head: LLNode, k: number): LLNode { - // If k is less than or equal to 0, no node needs to be removed. - if (k <= 0) - return head; // A dummy node to ensure there's a node before 'head' in case we // need to remove the head node. let dummy: LLNode = new ListNode(-1); From b6281d87810d60fe15a957c12a82dbe8ca5ef98f Mon Sep 17 00:00:00 2001 From: aikhelis Date: Sun, 2 Feb 2025 12:16:01 +0000 Subject: [PATCH 23/27] ts-3: added non-null assertions to inform typescript checks --- typescript/Linked Lists/palindromic_linked_list.ts | 8 ++++---- typescript/Linked Lists/remove_kth_last_node.ts | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/typescript/Linked Lists/palindromic_linked_list.ts b/typescript/Linked Lists/palindromic_linked_list.ts index 3401527..3cb7d29 100644 --- a/typescript/Linked Lists/palindromic_linked_list.ts +++ b/typescript/Linked Lists/palindromic_linked_list.ts @@ -19,10 +19,10 @@ function palindromicLinkedList(head: LLNode): boolean { let ptr1 = head, ptr2 = secondHead; let res = true; while (ptr2) { - if (ptr1.val !== ptr2.val) { + if (ptr1!.val !== ptr2.val) { res = false; } - ptr1 = ptr1.next, ptr2 = ptr2.next; + ptr1 = ptr1!.next, ptr2 = ptr2.next; } return res; } @@ -45,8 +45,8 @@ function findMiddle(head: LLNode): LLNode { let slow: LLNode = head; let fast: LLNode = head; while (fast && fast.next) { - slow = slow.next; - fast = fast.next.next; + slow = slow!.next; + fast = fast.next!.next; } return slow; } diff --git a/typescript/Linked Lists/remove_kth_last_node.ts b/typescript/Linked Lists/remove_kth_last_node.ts index 2e2d942..11d271f 100644 --- a/typescript/Linked Lists/remove_kth_last_node.ts +++ b/typescript/Linked Lists/remove_kth_last_node.ts @@ -28,9 +28,9 @@ function removeKthLastNode(head: LLNode, k: number): LLNode { // k nodes behind. while (leader.next !== null){ leader = leader.next; - trailer = trailer.next; + trailer = trailer!.next; } // Remove the kth node from the end. - trailer.next = trailer.next.next; + trailer!.next = trailer!.next!.next; return dummy.next; } \ No newline at end of file From 315a5f26a974c4c05daac34be150d4ca6e97a86a Mon Sep 17 00:00:00 2001 From: aikhelis Date: Sun, 2 Feb 2025 12:40:01 +0000 Subject: [PATCH 24/27] ts-3: lru cavhe --- typescript/Linked Lists/lru_cache.ts | 70 ++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 typescript/Linked Lists/lru_cache.ts diff --git a/typescript/Linked Lists/lru_cache.ts b/typescript/Linked Lists/lru_cache.ts new file mode 100644 index 0000000..8f3ce98 --- /dev/null +++ b/typescript/Linked Lists/lru_cache.ts @@ -0,0 +1,70 @@ +class DoublyLinkedListNode { + key: number; val: number; + prev: DoublyLinkedListNode | null; + next: DoublyLinkedListNode | null; + + constructor(key: number, val: number) { + this.key = key; + this.val = val; + this.prev = null; + this.next = null; + } +} + +class LRUCache { + capacity: number; + hashmap: Map; + head: DoublyLinkedListNode; tail: DoublyLinkedListNode; + + constructor(capacity: number) { + this.capacity = capacity; + // A hash map that maps keys to nodes. + this.hashmap = new Map(); + // Initialize the head and tail dummy nodes and connect them to + // each other to establish a basic two-node doubly linked list. + this.head = new DoublyLinkedListNode(-1, -1); + this.tail = new DoublyLinkedListNode(-1, -1); + this.head.next = this.tail; + this.tail.prev = this.head; + } + + get(key: number): number { + if (!this.hashmap.has(key)) + return -1; + // To make this key the most recently used, remove its node and + // re-add it to the tail of the linked list. + const node = this.hashmap.get(key)!; + this.removeNode(node); + this.addToTail(node); + return node.val; + } + + put(key: number, val: number): void { + // If a node with this key already exists, remove it from the + // linked list. + if (this.hashmap.has(key)) + this.removeNode(this.hashmap.get(key)!); + const node = new DoublyLinkedListNode(key, val); + this.hashmap.set(key, node); + // Remove the least recently used node from the cache if adding + // this new node will result in an overflow. + if (this.hashmap.size > this.capacity) { + this.hashmap.delete(this.head.next!.key); + this.removeNode(this.head.next!); + } + this.addToTail(node); + } + + addToTail(node: DoublyLinkedListNode): void { + const prevNode = this.tail.prev; + node.prev = prevNode; + node.next = this.tail; + prevNode!.next = node; + this.tail.prev = node; + } + + removeNode(node: DoublyLinkedListNode): void { + node.prev!.next = node.next; + node.next!.prev = node.prev; + } +} From a0b22542d865cc744ee7eb749c2c4c3390f7e9cc Mon Sep 17 00:00:00 2001 From: aikhelis Date: Sun, 2 Feb 2025 12:42:26 +0000 Subject: [PATCH 25/27] ts-1: address typescript warning --- typescript/Two Pointers/triplet_sum_brute_force.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/typescript/Two Pointers/triplet_sum_brute_force.ts b/typescript/Two Pointers/triplet_sum_brute_force.ts index 659a795..88d7fb9 100644 --- a/typescript/Two Pointers/triplet_sum_brute_force.ts +++ b/typescript/Two Pointers/triplet_sum_brute_force.ts @@ -16,5 +16,5 @@ function tripletSumBruteForce(nums: number[]): number[][] { } } // [javascript] convert the Set back into an array of triplets. - return Array.from(triplets).map(JSON.parse); + return Array.from(triplets).map((str) => JSON.parse(str)); } From acea417e3700f93b0321e95ec020f7498451c2af Mon Sep 17 00:00:00 2001 From: aikhelis Date: Mon, 3 Feb 2025 13:15:41 +0000 Subject: [PATCH 26/27] ts-3: addressed review comments (imports, naming, ditch extra types) --- .../Linked Lists/flatten_multi_level_list.ts | 21 ++++++------ .../Linked Lists/linked_list_intersection.ts | 32 +++++++++---------- .../Linked Lists/linked_list_reversal.ts | 21 ++++++------ .../linked_list_reversal_recursive.ts | 17 +++++----- typescript/Linked Lists/lru_cache.ts | 5 ++- .../Linked Lists/palindromic_linked_list.ts | 25 +++++++-------- .../Linked Lists/remove_kth_last_node.ts | 18 +++++------ 7 files changed, 71 insertions(+), 68 deletions(-) diff --git a/typescript/Linked Lists/flatten_multi_level_list.ts b/typescript/Linked Lists/flatten_multi_level_list.ts index 9cc5e1c..57aa7ec 100644 --- a/typescript/Linked Lists/flatten_multi_level_list.ts +++ b/typescript/Linked Lists/flatten_multi_level_list.ts @@ -1,23 +1,26 @@ -/* Definition of MultiLevelListNode: -class MultieLevelListNode { - val: number; next: MLLNode; child: MLLNode; +import { MultiLevelListNode } from "./ds"; + +/* Definition of MultiLevelListNode: +class MultiLevelListNode { + val: number; + next: MultiLevelListNode | null; + child: MultiLevelListNode | null; constructor(val: number){ this.val = val; this.next = null; this.child = null; } -} -type MLLNode = MultieLevelListNode | null; -*/ +}*/ + -function flattenMultiLevelList(head: MLLNode): MLLNode { +function flattenMultiLevelList(head: MultiLevelListNode | null): MultiLevelListNode | null { if (!head) return head; - let tail: MLLNode = head; + let tail: MultiLevelListNode | null = head; // Find the tail of the linked list at the first level. while (tail.next !== null) tail = tail.next; - let curr: MLLNode = head; + let curr: MultiLevelListNode | null = head; // Process each node at the current level. If a node has a child linked list, // append it to the tail and then update the tail to the end of the extended // linked list. Continue until all nodes at the current level are processed. diff --git a/typescript/Linked Lists/linked_list_intersection.ts b/typescript/Linked Lists/linked_list_intersection.ts index ab3ca68..64ee7ea 100644 --- a/typescript/Linked Lists/linked_list_intersection.ts +++ b/typescript/Linked Lists/linked_list_intersection.ts @@ -1,29 +1,29 @@ +import { ListNode } from './ds'; + /* Definition of ListNode: class ListNode { - val: number; - next: LLNode; - constructor(val: number, next: LLNode = null){ + val: number; next: ListNode | null; + constructor(val: number){ this.val = val; - this.next = next; + this.next = null; } -} -type LLNode = ListNode | null; -*/ +}*/ + -function linkedListIntersection(head_A: LLNode, head_B: LLNode): LLNode { - let ptr_A = head_A, ptr_B = head_B; - // Traverse through list A with 'ptr_A' and list B with 'ptr_B' +function linkedListIntersection(headA: ListNode | null, headB: ListNode | null): ListNode | null { + let ptrA = headA, ptrB = headB; + // Traverse through list A with 'ptrA' and list B with 'ptrB' // until they meet. - while (ptr_A !== ptr_B) { - // Traverse list A -> list B by first traversing 'ptr_A' and + while (ptrA !== ptrB) { + // Traverse list A -> list B by first traversing 'ptrA' and // then, upon reaching the end of list A, continue the // traversal from the head of list B. - ptr_A = ptr_A !== null ? ptr_A.next : head_B; + ptrA = ptrA !== null ? ptrA.next : headB; // Simultaneously, traverse list B -> list A. - ptr_B = ptr_B !== null ? ptr_B.next : head_A; + ptrB = ptrB !== null ? ptrB.next : headA; } - // At this point, 'ptr_A' and 'ptr_B' either point to the + // At this point, 'ptrA' and 'ptrB' either point to the // intersection node or both are null if the lists do not // intersect. Return either pointer. - return ptr_A; + return ptrA; } diff --git a/typescript/Linked Lists/linked_list_reversal.ts b/typescript/Linked Lists/linked_list_reversal.ts index 323755e..73fe4a0 100644 --- a/typescript/Linked Lists/linked_list_reversal.ts +++ b/typescript/Linked Lists/linked_list_reversal.ts @@ -1,22 +1,21 @@ +import { ListNode } from './ds'; + /* Definition of ListNode: class ListNode { - val: number; - next: LLNode; - constructor(val: number, next: LLNode = null){ + val: number; next: ListNode | null; + constructor(val: number){ this.val = val; - this.next = next; + this.next = null; } -} -type LLNode = ListNode | null; -*/ +}*/ -function linkedListReversal(head: LLNode): LLNode { - let currNode: LLNode = head; - let prevNode: LLNode = null; +function linkedListReversal(head: ListNode | null): ListNode | null { + let currNode: ListNode | null = head; + let prevNode: ListNode | null = null; // Reverse the direction of each node's pointer until 'currNode' // is null. while (currNode !== null){ - const nextNode: LLNode = currNode.next; + const nextNode: ListNode | null = currNode.next; currNode.next = prevNode; prevNode = currNode; currNode = nextNode; diff --git a/typescript/Linked Lists/linked_list_reversal_recursive.ts b/typescript/Linked Lists/linked_list_reversal_recursive.ts index 4198840..f4ae00b 100644 --- a/typescript/Linked Lists/linked_list_reversal_recursive.ts +++ b/typescript/Linked Lists/linked_list_reversal_recursive.ts @@ -1,21 +1,20 @@ +import { ListNode } from './ds'; + /* Definition of ListNode: class ListNode { - val: number; - next: LLNode; - constructor(val: number, next: LLNode = null){ + val: number; next: ListNode | null; + constructor(val: number){ this.val = val; - this.next = next; + this.next = null; } -} -type LLNode = ListNode | null; -*/ +}*/ -function linkedListReversalRecursive(head: LLNode): LLNode { +function linkedListReversalRecursive(head: ListNode | null): ListNode | null { // Base cases. if (!head || !head.next) return head; // Recursively reverse the sublist starting from the next node. - const newHead: LLNode = linkedListReversalRecursive(head.next); + const newHead: ListNode | null = linkedListReversalRecursive(head.next); // Connect the reversed linked list to the head node to fully // reverse the entire linked list. head.next.next = head; diff --git a/typescript/Linked Lists/lru_cache.ts b/typescript/Linked Lists/lru_cache.ts index 8f3ce98..c2e24ce 100644 --- a/typescript/Linked Lists/lru_cache.ts +++ b/typescript/Linked Lists/lru_cache.ts @@ -1,3 +1,6 @@ +import { DoublyLinkedListNode } from './ds'; + +/* Definition of DoublyLinkedListNode: class DoublyLinkedListNode { key: number; val: number; prev: DoublyLinkedListNode | null; @@ -9,7 +12,7 @@ class DoublyLinkedListNode { this.prev = null; this.next = null; } -} +}*/ class LRUCache { capacity: number; diff --git a/typescript/Linked Lists/palindromic_linked_list.ts b/typescript/Linked Lists/palindromic_linked_list.ts index 3cb7d29..6bce191 100644 --- a/typescript/Linked Lists/palindromic_linked_list.ts +++ b/typescript/Linked Lists/palindromic_linked_list.ts @@ -1,16 +1,15 @@ -/* Definition of ListNode: +import { ListNode } from './ds'; + +/* Definition of ListNode: class ListNode { - val: number; - next: LLNode; + val: number; next: ListNode | null; constructor(val: number){ this.val = val; this.next = null; } -} -type LLNode = ListNode | null; -*/ +}*/ -function palindromicLinkedList(head: LLNode): boolean { +function palindromicLinkedList(head: ListNode | null): boolean { // Find the middle of the linked list and then reverse the second half of the // linked list starting at this midpoint. const mid = findMiddle(head); @@ -28,9 +27,9 @@ function palindromicLinkedList(head: LLNode): boolean { } // From the 'Reverse Linked List' problem. -function reverseList(head: LLNode): LLNode { - let prevNode: LLNode = null; - let currNode: LLNode = head; +function reverseList(head: ListNode | null): ListNode | null { + let prevNode: ListNode | null = null; + let currNode: ListNode | null = head; while (currNode) { const nextNode = currNode.next; currNode.next = prevNode; @@ -41,9 +40,9 @@ function reverseList(head: LLNode): LLNode { } // From the 'Linked List Midpoint' problem. -function findMiddle(head: LLNode): LLNode { - let slow: LLNode = head; - let fast: LLNode = head; +function findMiddle(head: ListNode | null): ListNode | null { + let slow: ListNode | null = head; + let fast: ListNode | null = head; while (fast && fast.next) { slow = slow!.next; fast = fast.next!.next; diff --git a/typescript/Linked Lists/remove_kth_last_node.ts b/typescript/Linked Lists/remove_kth_last_node.ts index 11d271f..9df5830 100644 --- a/typescript/Linked Lists/remove_kth_last_node.ts +++ b/typescript/Linked Lists/remove_kth_last_node.ts @@ -1,21 +1,21 @@ -/* Definition of ListNode: +import { ListNode } from './ds'; + +/* Definition of ListNode: class ListNode { - val: number; - next: LLNode; + val: number; next: ListNode | null; constructor(val: number){ this.val = val; this.next = null; } -} -type LLNode = ListNode | null; -*/ +}*/ -function removeKthLastNode(head: LLNode, k: number): LLNode { +function removeKthLastNode(head: ListNode | null, k: number): ListNode | null { // A dummy node to ensure there's a node before 'head' in case we // need to remove the head node. - let dummy: LLNode = new ListNode(-1); + let dummy: ListNode | null = new ListNode(-1); dummy.next = head; - let trailer: LLNode = dummy, leader: LLNode = dummy; + let trailer: ListNode | null = dummy; + let leader: ListNode | null = dummy; // Advance 'leader' k steps ahead. for (let i = 0; i < k; i++){ leader = leader.next; From 1af9cddf53e83065f2f874db7106234e4248ce25 Mon Sep 17 00:00:00 2001 From: aikhelis Date: Tue, 4 Feb 2025 11:48:02 +0000 Subject: [PATCH 27/27] ts-3: double linked list node defined in the same file --- typescript/Linked Lists/lru_cache.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/typescript/Linked Lists/lru_cache.ts b/typescript/Linked Lists/lru_cache.ts index c2e24ce..8f3ce98 100644 --- a/typescript/Linked Lists/lru_cache.ts +++ b/typescript/Linked Lists/lru_cache.ts @@ -1,6 +1,3 @@ -import { DoublyLinkedListNode } from './ds'; - -/* Definition of DoublyLinkedListNode: class DoublyLinkedListNode { key: number; val: number; prev: DoublyLinkedListNode | null; @@ -12,7 +9,7 @@ class DoublyLinkedListNode { this.prev = null; this.next = null; } -}*/ +} class LRUCache { capacity: number;