From c43d9234c782326dd3013b66aaebececd2276b4e Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Tue, 1 Oct 2024 19:29:02 +0530 Subject: [PATCH 01/25] Add graph algorithms article --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 0c649c7..d1f3676 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ This repository contains awesome LeetCode resources to learn Data Structures and - [Greedy Algorithm](https://www.freecodecamp.org/news/greedy-algorithms/) - [Dynamic Programming](https://medium.com/basecs/less-repetition-more-dynamic-programming-43d29830a630) - [Graph Theory](https://medium.com/basecs/a-gentle-introduction-to-graph-theory-77969829ead8) +- [Important Graph Algorithms](https://blog.algomaster.io/p/master-graph-algorithms-for-coding) - [DFS Traversal](https://medium.com/basecs/deep-dive-through-a-graph-dfs-traversal-8177df5d0f13) - [BFS Traversal](https://medium.com/basecs/going-broad-in-a-graph-bfs-traversal-959bd1a09255) - [Union-Find](https://leetcode.com/discuss/general-discussion/1072418/Disjoint-Set-Union-(DSU)Union-Find-A-Complete-Guide) From 18edf0085664148cd3e939ada8de9c6af6b00cce Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Mon, 14 Oct 2024 14:04:24 +0530 Subject: [PATCH 02/25] Add fast and slow pointers code --- patterns/c#/FastAndSlowPointers.cs | 95 ++++++++++++++++ patterns/c++/FastAndSlowPointers.cpp | 100 +++++++++++++++++ patterns/go/fast_and_slow_pointers.go | 98 ++++++++++++++++ patterns/java/FastAndSlowPointers.java | 123 +++++++++++++++++++++ patterns/javascript/fastAndSlowPointers.js | 84 ++++++++++++++ patterns/python/fast_and_slow_pointers.py | 68 ++++++++++++ patterns/typescript/fastAndSlowPointers.ts | 86 ++++++++++++++ 7 files changed, 654 insertions(+) create mode 100644 patterns/c#/FastAndSlowPointers.cs create mode 100644 patterns/c++/FastAndSlowPointers.cpp create mode 100644 patterns/go/fast_and_slow_pointers.go create mode 100644 patterns/java/FastAndSlowPointers.java create mode 100644 patterns/javascript/fastAndSlowPointers.js create mode 100644 patterns/python/fast_and_slow_pointers.py create mode 100644 patterns/typescript/fastAndSlowPointers.ts diff --git a/patterns/c#/FastAndSlowPointers.cs b/patterns/c#/FastAndSlowPointers.cs new file mode 100644 index 0000000..280276d --- /dev/null +++ b/patterns/c#/FastAndSlowPointers.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; + +public class ListNode { + public int val; + public ListNode next; + public ListNode(int x) { + val = x; + next = null; + } +} + +public class FastAndSlowPointers { + // LeetCode 141 - Linked List Cycle (HashSet Approach) + public bool HasCycleHashSetApproach(ListNode head) { + HashSet visited = new HashSet(); + ListNode current = head; + while (current != null) { + if (visited.Contains(current)) { + return true; // Cycle detected + } + visited.Add(current); + current = current.next; + } + return false; // No cycle + } + + // LeetCode 141 - Linked List Cycle (Fast and Slow Pointer Approach) + public bool HasCycleFastAndSlowPointersApproach(ListNode head) { + if (head == null || head.next == null) return false; + ListNode slow = head, fast = head; + while (fast != null && fast.next != null) { + slow = slow.next; + fast = fast.next.next; + if (slow == fast) return true; + } + return false; + } + + // LeetCode 876 - Middle of the Linked List (Counting Approach) + public ListNode MiddleNodeCountingApproach(ListNode head) { + int count = 0; + ListNode current = head; + while (current != null) { + count++; + current = current.next; + } + current = head; + for (int i = 0; i < count / 2; i++) { + current = current.next; + } + return current; + } + + // LeetCode 876 - Middle of the Linked List (Fast and Slow Pointer Approach) + public ListNode MiddleNodeFastAndSlowPointerApproach(ListNode head) { + ListNode slow = head, fast = head; + while (fast != null && fast.next != null) { + slow = slow.next; + fast = fast.next.next; + } + return slow; + } + + // LeetCode 202 - Happy Number (HashSet Approach) + private int GetSumOfSquares(int n) { + int sum = 0; + while (n > 0) { + int digit = n % 10; + sum += digit * digit; + n /= 10; + } + return sum; + } + + public bool IsHappyHashSetApproach(int n) { + HashSet seen = new HashSet(); + while (n != 1 && !seen.Contains(n)) { + seen.Add(n); + n = GetSumOfSquares(n); + } + return n == 1; + } + + // LeetCode 202 - Happy Number (Fast and Slow Pointer Approach) + public bool IsHappyFastAndSlowPointersApproach(int n) { + int slow = n; + int fast = GetSumOfSquares(n); + while (fast != 1 && slow != fast) { + slow = GetSumOfSquares(slow); + fast = GetSumOfSquares(GetSumOfSquares(fast)); + } + return fast == 1; + } +} \ No newline at end of file diff --git a/patterns/c++/FastAndSlowPointers.cpp b/patterns/c++/FastAndSlowPointers.cpp new file mode 100644 index 0000000..b296339 --- /dev/null +++ b/patterns/c++/FastAndSlowPointers.cpp @@ -0,0 +1,100 @@ +#include +using namespace std; + +class ListNode { +public: + int val; + ListNode* next; + ListNode(int x) : val(x), next(nullptr) {} +}; + +class FastAndSlowPointers { +public: + // LeetCode 141 - Linked List Cycle (HashSet Approach) + bool hasCycleHashSetApproach(ListNode* head) { + unordered_set visited; + ListNode* current = head; + while (current != nullptr) { + if (visited.find(current) != visited.end()) { + return true; // Cycle detected + } + visited.insert(current); + current = current->next; + } + return false; // No cycle + } + + // LeetCode 141 - Linked List Cycle (Fast and Slow Pointer Approach) + bool hasCycleFastAndSlowPointersApproach(ListNode* head) { + if (head == nullptr || head->next == nullptr) { + return false; + } + ListNode* slow = head; + ListNode* fast = head; + while (fast != nullptr && fast->next != nullptr) { + slow = slow->next; + fast = fast->next->next; + if (slow == fast) { + return true; // Cycle detected + } + } + return false; // No cycle + } + + // LeetCode 876 - Middle of the Linked List (Counting Approach) + ListNode* middleNodeCountingApproach(ListNode* head) { + int count = 0; + ListNode* current = head; + while (current != nullptr) { + count++; + current = current->next; + } + current = head; + for (int i = 0; i < count / 2; i++) { + current = current->next; + } + return current; + } + + // LeetCode 876 - Middle of the Linked List (Fast and Slow Pointer Approach) + ListNode* middleNodeFastAndSlowPointerApproach(ListNode* head) { + ListNode* slow = head; + ListNode* fast = head; + while (fast != nullptr && fast->next != nullptr) { + slow = slow->next; + fast = fast->next->next; + } + return slow; + } + + // LeetCode 202 - Happy Number (HashSet Approach) + int getSumOfSquares(int n) { + int sum = 0; + while (n > 0) { + int digit = n % 10; + sum += digit * digit; + n /= 10; + } + return sum; + } + + bool isHappyHashSetApproach(int n) { + unordered_set seen; + while (n != 1 && seen.find(n) == seen.end()) { + seen.insert(n); + n = getSumOfSquares(n); + } + return n == 1; + } + + // LeetCode 202 - Happy Number (Fast and Slow Pointer Approach) + bool isHappyFastAndSlowPointersApproach(int n) { + int slow = n; + int fast = getSumOfSquares(n); + while (fast != 1 && slow != fast) { + slow = getSumOfSquares(slow); + fast = getSumOfSquares(getSumOfSquares(fast)); + } + return fast == 1; + } +}; \ No newline at end of file diff --git a/patterns/go/fast_and_slow_pointers.go b/patterns/go/fast_and_slow_pointers.go new file mode 100644 index 0000000..f4bb6e0 --- /dev/null +++ b/patterns/go/fast_and_slow_pointers.go @@ -0,0 +1,98 @@ +package main + +import "fmt" + +type ListNode struct { + Val int + Next *ListNode +} + +// LeetCode 141 - Linked List Cycle (HashSet Approach) +func hasCycleHashSetApproach(head *ListNode) bool { + visited := map[*ListNode]bool{} + current := head + for current != nil { + if visited[current] { + return true + } + visited[current] = true + current = current.Next + } + return false +} + +// LeetCode 141 - Linked List Cycle (Fast and Slow Pointer Approach) +func hasCycleFastAndSlowPointersApproach(head *ListNode) bool { + if head == nil || head.Next == nil { + return false + } + slow, fast := head, head + for fast != nil && fast.Next != nil { + slow = slow.Next + fast = fast.Next.Next + if slow == fast { + return true + } + } + return false +} + +// LeetCode 876 - Middle of the Linked List (Counting Approach) +func middleNodeCountingApproach(head *ListNode) *ListNode { + count := 0 + current := head + for current != nil { + count++ + current = current.Next + } + current = head + for i := 0; i < count/2; i++ { + current = current.Next + } + return current +} + +// LeetCode 876 - Middle of the Linked List (Fast and Slow Pointer Approach) +func middleNodeFastAndSlowPointerApproach(head *ListNode) *ListNode { + slow, fast := head, head + for fast != nil && fast.Next != nil { + slow = slow.Next + fast = fast.Next.Next + } + return slow +} + +// LeetCode 202 - Happy Number (HashSet Approach) +func getSumOfSquares(n int) int { + sum := 0 + for n > 0 { + digit := n % 10 + sum += digit * digit + n /= 10 + } + return sum +} + +func isHappyHashSetApproach(n int) bool { + seen := map[int]bool{} + for n != 1 && !seen[n] { + seen[n] = true + n = getSumOfSquares(n) + } + return n == 1 +} + +// LeetCode 202 - Happy Number (Fast and Slow Pointer Approach) +func isHappyFastAndSlowPointersApproach(n int) bool { + slow := n + fast := getSumOfSquares(n) + for fast != 1 && slow != fast { + slow = getSumOfSquares(slow) + fast = getSumOfSquares(getSumOfSquares(fast)) + } + return fast == 1 +} + +func main() { + // You can test the implementations here +} \ No newline at end of file diff --git a/patterns/java/FastAndSlowPointers.java b/patterns/java/FastAndSlowPointers.java new file mode 100644 index 0000000..666e433 --- /dev/null +++ b/patterns/java/FastAndSlowPointers.java @@ -0,0 +1,123 @@ +package patterns.java; + +import java.util.HashSet; + +public class FastAndSlowPointers { + + class ListNode { + int val; + ListNode next; + ListNode(int x) { + val = x; + next = null; + } + } + +/* + * ********** LeetCode 141 - Linked List Cycle (https://leetcode.com/problems/linked-list-cycle/) ********** +*/ + + public boolean hasCycleHashSetAppraoch(ListNode head) { + HashSet visited = new HashSet<>(); + ListNode current = head; + while (current != null) { + if (visited.contains(current)) { + return true; // Cycle detected + } + visited.add(current); + current = current.next; + } + return false; // No cycle + } + + public boolean hasCycleFastAndSlowPointersAppraoch(ListNode head) { + if (head == null || head.next == null) { + return false; // No cycle if the list is empty or has only one node + } + + ListNode slow = head; + ListNode fast = head; + + while (fast != null && fast.next != null) { + slow = slow.next; // Move slow pointer by 1 step + fast = fast.next.next; // Move fast pointer by 2 steps + + if (slow == fast) { + return true; // Cycle detected + } + } + + return false; // No cycle + } + +/* + * ********** LeetCode 876 - Middle of the Linked List (https://leetcode.com/problems/middle-of-the-linked-list/description/) ********** +*/ + + public ListNode middleNodeCountingApproach(ListNode head) { + int count = 0; + ListNode current = head; + + // First pass to count the number of nodes + while (current != null) { + count++; + current = current.next; + } + + // Second pass to find the middle node + current = head; + for (int i = 0; i < count / 2; i++) { + current = current.next; + } + + return current; // This will be the middle node + } + + public ListNode middleNodeFastAndSlowPointerApproach(ListNode head) { + ListNode slow = head; + ListNode fast = head; + + // Move slow by 1 and fast by 2 steps + while (fast != null && fast.next != null) { + slow = slow.next; + fast = fast.next.next; + } + + return slow; // Slow will be at the middle node + } + +/* + * ********** LeetCode 202 - Happy Number (https://leetcode.com/problems/happy-number/description/) ********** +*/ + + private int getSumOfSquares(int n) { + int sum = 0; + while (n > 0) { + int digit = n % 10; + sum += digit * digit; + n /= 10; + } + return sum; + } + + public boolean isHappyHashSetApproach(int n) { + HashSet seen = new HashSet<>(); + while (n != 1 && !seen.contains(n)) { + seen.add(n); + n = getSumOfSquares(n); + } + return n == 1; + } + + public boolean isHappyFastAndSlowPointersApproach(int n) { + int slow = n; + int fast = getSumOfSquares(n); + + while (fast != 1 && slow != fast) { + slow = getSumOfSquares(slow); // Move slow by 1 step + fast = getSumOfSquares(getSumOfSquares(fast)); // Move fast by 2 steps + } + + return fast == 1; + } +} \ No newline at end of file diff --git a/patterns/javascript/fastAndSlowPointers.js b/patterns/javascript/fastAndSlowPointers.js new file mode 100644 index 0000000..0ddc20a --- /dev/null +++ b/patterns/javascript/fastAndSlowPointers.js @@ -0,0 +1,84 @@ +class ListNode { + constructor(x) { + this.val = x; + this.next = null; + } +} + +class FastAndSlowPointers { + // LeetCode 141 - Linked List Cycle (HashSet Approach) + hasCycleHashSetApproach(head) { + const visited = new Set(); + let current = head; + while (current) { + if (visited.has(current)) { + return true; + } + visited.add(current); + current = current.next; + } + return false; + } + + // LeetCode 141 - Linked List Cycle (Fast and Slow Pointer Approach) + hasCycleFastAndSlowPointersApproach(head) { + if (!head || !head.next) return false; + let slow = head, fast = head; + while (fast && fast.next) { + slow = slow.next; + fast = fast.next.next; + if (slow === fast) return true; + } + return false; + } + + // LeetCode 876 - Middle of the Linked List (Counting Approach) + middleNodeCountingApproach(head) { + let count = 0; + let current = head; + while (current) { + count++; + current = current.next; + } + current = head; + for (let i = 0; i < Math.floor(count / 2); i++) { + current = current.next; + } + return current; + } + + // LeetCode 876 - Middle of the Linked List (Fast and Slow Pointer Approach) + middleNodeFastAndSlowPointerApproach(head) { + let slow = head, fast = head; + while (fast && fast.next) { + slow = slow.next; + fast = fast.next.next; + } + return slow; + } + + // LeetCode 202 - Happy Number (HashSet Approach) + getSumOfSquares(n) { + return String(n).split('').reduce((sum, digit) => sum + digit * digit, 0); + } + + isHappyHashSetApproach(n) { + const seen = new Set(); + while (n !== 1 && !seen.has(n)) { + seen.add(n); + n = this.getSumOfSquares(n); + } + return n === 1; + } + + // LeetCode 202 - Happy Number (Fast and Slow Pointer Approach) + isHappyFastAndSlowPointersApproach(n) { + let slow = n; + let fast = this.getSumOfSquares(n); + while (fast !== 1 && slow !== fast) { + slow = this.getSumOfSquares(slow); + fast = this.getSumOfSquares(this.getSumOfSquares(fast)); + } + return fast === 1; + } +} \ No newline at end of file diff --git a/patterns/python/fast_and_slow_pointers.py b/patterns/python/fast_and_slow_pointers.py new file mode 100644 index 0000000..be6ed55 --- /dev/null +++ b/patterns/python/fast_and_slow_pointers.py @@ -0,0 +1,68 @@ +class ListNode: + def __init__(self, x): + self.val = x + self.next = None + +class FastAndSlowPointers: + # LeetCode 141 - Linked List Cycle (HashSet Approach) + def hasCycleHashSetApproach(self, head): + visited = set() + current = head + while current: + if current in visited: + return True + visited.add(current) + current = current.next + return False + + # LeetCode 141 - Linked List Cycle (Fast and Slow Pointer Approach) + def hasCycleFastAndSlowPointersApproach(self, head): + if not head or not head.next: + return False + slow, fast = head, head + while fast and fast.next: + slow = slow.next + fast = fast.next.next + if slow == fast: + return True + return False + + # LeetCode 876 - Middle of the Linked List (Counting Approach) + def middleNodeCountingApproach(self, head): + count = 0 + current = head + while current: + count += 1 + current = current.next + current = head + for _ in range(count // 2): + current = current.next + return current + + # LeetCode 876 - Middle of the Linked List (Fast and Slow Pointer Approach) + def middleNodeFastAndSlowPointerApproach(self, head): + slow, fast = head, head + while fast and fast.next: + slow = slow.next + fast = fast.next.next + return slow + + # LeetCode 202 - Happy Number (HashSet Approach) + def getSumOfSquares(self, n): + return sum(int(digit)**2 for digit in str(n)) + + def isHappyHashSetApproach(self, n): + seen = set() + while n != 1 and n not in seen: + seen.add(n) + n = self.getSumOfSquares(n) + return n == 1 + + # LeetCode 202 - Happy Number (Fast and Slow Pointer Approach) + def isHappyFastAndSlowPointersApproach(self, n): + slow = n + fast = self.getSumOfSquares(n) + while fast != 1 and slow != fast: + slow = self.getSumOfSquares(slow) + fast = self.getSumOfSquares(self.getSumOfSquares(fast)) + return fast == 1 \ No newline at end of file diff --git a/patterns/typescript/fastAndSlowPointers.ts b/patterns/typescript/fastAndSlowPointers.ts new file mode 100644 index 0000000..526baae --- /dev/null +++ b/patterns/typescript/fastAndSlowPointers.ts @@ -0,0 +1,86 @@ +class ListNode { + val: number; + next: ListNode | null = null; + constructor(x: number) { + this.val = x; + } +} + +class FastAndSlowPointers { + // LeetCode 141 - Linked List Cycle (HashSet Approach) + hasCycleHashSetApproach(head: ListNode | null): boolean { + const visited = new Set(); + let current = head; + while (current) { + if (visited.has(current)) { + return true; + } + visited.add(current); + current = current.next; + } + return false; + } + + // LeetCode 141 - Linked List Cycle (Fast and Slow Pointer Approach) + hasCycleFastAndSlowPointersApproach(head: ListNode | null): boolean { + if (!head || !head.next) return false; + let slow: ListNode | null = head; + let fast: ListNode | null = head; + while (fast && fast.next) { + slow = slow!.next; + fast = fast.next.next; + if (slow === fast) return true; + } + return false; + } + + // LeetCode 876 - Middle of the Linked List (Counting Approach) + middleNodeCountingApproach(head: ListNode | null): ListNode | null { + let count = 0; + let current = head; + while (current) { + count++; + current = current.next; + } + current = head; + for (let i = 0; i < Math.floor(count / 2); i++) { + current = current!.next; + } + return current; + } + + // LeetCode 876 - Middle of the Linked List (Fast and Slow Pointer Approach) + middleNodeFastAndSlowPointerApproach(head: ListNode | null): ListNode | null { + let slow = head, fast = head; + while (fast && fast.next) { + slow = slow!.next; + fast = fast.next.next; + } + return slow; + } + + // LeetCode 202 - Happy Number (HashSet Approach) + getSumOfSquares(n: number): number { + return String(n).split('').reduce((sum, digit) => sum + Number(digit) ** 2, 0); + } + + isHappyHashSetApproach(n: number): boolean { + const seen = new Set(); + while (n !== 1 && !seen.has(n)) { + seen.add(n); + n = this.getSumOfSquares(n); + } + return n === 1; + } + + // LeetCode 202 - Happy Number (Fast and Slow Pointer Approach) + isHappyFastAndSlowPointersApproach(n: number): boolean { + let slow = n; + let fast = this.getSumOfSquares(n); + while (fast !== 1 && slow !== fast) { + slow = this.getSumOfSquares(slow); + fast = this.getSumOfSquares(this.getSumOfSquares(fast)); + } + return fast === 1; + } +} \ No newline at end of file From d590ec33a44ab1967673d343d35ef721399ccf4e Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Mon, 14 Oct 2024 14:07:48 +0530 Subject: [PATCH 03/25] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d1f3676..99444f5 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ This repository contains awesome LeetCode resources to learn Data Structures and - [20 DP Patterns](https://blog.algomaster.io/p/20-patterns-to-master-dynamic-programming) - [Prefix Sum Pattern](https://blog.algomaster.io/p/f96dd3de-c89c-428e-a88d-b1f751a42a57) - [Two Pointers Pattern](https://blog.algomaster.io/p/69025a2e-b0d5-4705-8507-bba16c2691f1) -- [Fast and Slow Pointers Pattern](https://blog.algomaster.io/p/7dcce8e9-beee-4fef-8874-7aae025031b1) +- [Linked List In-place Reversal Pattern](https://blog.algomaster.io/p/7dcce8e9-beee-4fef-8874-7aae025031b1) - [Sliding Window Pattern](https://blog.algomaster.io/p/f4412a17-7a3a-4d0b-8e39-9ea8f429bf7c) - [Top 'K' Elements Pattern](https://blog.algomaster.io/p/322aac40-c4d0-4e54-980d-b22d9eeebca6) - [Monotonic Stack Pattern](https://blog.algomaster.io/p/5dabff21-11f4-470d-8e38-76ff07c63fdf) From 7856de92131bb56b367b08ae2bf389c3be02916a Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Wed, 16 Oct 2024 17:04:39 +0530 Subject: [PATCH 04/25] add top k elements pattern code --- patterns/c#/TopKElements.cs | 103 ++++++++++++++++++ patterns/c++/TopKElements.cpp | 111 +++++++++++++++++++ patterns/go/top_k_elements.go | 96 +++++++++++++++++ patterns/java/TopKElements.java | 149 ++++++++++++++++++++++++++ patterns/javascript/top_k_elements.js | 88 +++++++++++++++ patterns/python/top_k_elements.py | 49 +++++++++ patterns/typescript/top_k_elements.ts | 88 +++++++++++++++ 7 files changed, 684 insertions(+) create mode 100644 patterns/c#/TopKElements.cs create mode 100644 patterns/c++/TopKElements.cpp create mode 100644 patterns/go/top_k_elements.go create mode 100644 patterns/java/TopKElements.java create mode 100644 patterns/javascript/top_k_elements.js create mode 100644 patterns/python/top_k_elements.py create mode 100644 patterns/typescript/top_k_elements.ts diff --git a/patterns/c#/TopKElements.cs b/patterns/c#/TopKElements.cs new file mode 100644 index 0000000..7b0b715 --- /dev/null +++ b/patterns/c#/TopKElements.cs @@ -0,0 +1,103 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +public class TopKElements { + + // K Largest Elements using Sorting + public int[] KLargestElementsSortingApproach(int[] nums, int k) { + Array.Sort(nums, (a, b) => b.CompareTo(a)); + return nums.Take(k).ToArray(); + } + + // K Largest Elements using Max Heap + public int[] KLargestElementsMaxHeapApproach(int[] nums, int k) { + PriorityQueue maxHeap = new PriorityQueue(Comparer.Create((a, b) => b - a)); + foreach (var num in nums) { + maxHeap.Enqueue(num, num); + } + var result = new int[k]; + for (int i = 0; i < k; i++) { + result[i] = maxHeap.Dequeue(); + } + return result; + } + + // K Largest Elements using Min Heap + public int[] KLargestElementsMinHeapApproach(int[] nums, int k) { + PriorityQueue minHeap = new PriorityQueue(); + for (int i = 0; i < k; i++) { + minHeap.Enqueue(nums[i], nums[i]); + } + for (int i = k; i < nums.Length; i++) { + minHeap.Enqueue(nums[i], nums[i]); + if (minHeap.Count > k) { + minHeap.Dequeue(); + } + } + var result = new int[k]; + for (int i = 0; i < k; i++) { + result[i] = minHeap.Dequeue(); + } + return result; + } + + // Top K Frequent Elements using Sorting + public int[] TopKFrequentElementsSortingApproach(int[] nums, int k) { + var frequencyMap = new Dictionary(); + foreach (var num in nums) { + if (!frequencyMap.ContainsKey(num)) { + frequencyMap[num] = 0; + } + frequencyMap[num]++; + } + + var sortedEntries = frequencyMap.OrderByDescending(e => e.Value).Take(k).Select(e => e.Key).ToArray(); + return sortedEntries; + } + + // Top K Frequent Elements using Min Heap + public int[] TopKFrequentElementsMinHeapApproach(int[] nums, int k) { + var frequencyMap = new Dictionary(); + foreach (var num in nums) { + if (!frequencyMap.ContainsKey(num)) { + frequencyMap[num] = 0; + } + frequencyMap[num]++; + } + + var minHeap = new PriorityQueue(Comparer.Create((a, b) => a.CompareTo(b))); + foreach (var entry in frequencyMap) { + minHeap.Enqueue(entry.Key, entry.Value); + if (minHeap.Count > k) { + minHeap.Dequeue(); + } + } + + var result = new int[k]; + for (int i = 0; i < k; i++) { + result[i] = minHeap.Dequeue(); + } + return result; + } + + // K Closest Points to Origin using Max Heap + private int GetDistance(int[] point) { + return point[0] * point[0] + point[1] * point[1]; + } + + public int[][] KClosestPointsToOriginMaxHeapApproach(int[][] points, int k) { + PriorityQueue maxHeap = new PriorityQueue(Comparer.Create((a, b) => b - a)); + foreach (var point in points) { + maxHeap.Enqueue(point, GetDistance(point)); + if (maxHeap.Count > k) { + maxHeap.Dequeue(); + } + } + var result = new int[k][]; + for (int i = 0; i < k; i++) { + result[i] = maxHeap.Dequeue(); + } + return result; + } +} \ No newline at end of file diff --git a/patterns/c++/TopKElements.cpp b/patterns/c++/TopKElements.cpp new file mode 100644 index 0000000..71625a6 --- /dev/null +++ b/patterns/c++/TopKElements.cpp @@ -0,0 +1,111 @@ +#include +#include +#include +#include +#include + +using namespace std; + +class TopKElements { +public: + // K Largest Elements using Sorting + vector kLargestElementsSortingAppraoch(vector& nums, int k) { + sort(nums.begin(), nums.end(), greater()); + return vector(nums.begin(), nums.begin() + k); + } + + // K Largest Elements using Max Heap + vector kLargestElementsMaxHeapAppraoch(vector& nums, int k) { + priority_queue maxHeap(nums.begin(), nums.end()); + vector result; + for (int i = 0; i < k; i++) { + result.push_back(maxHeap.top()); + maxHeap.pop(); + } + return result; + } + + // K Largest Elements using Min Heap + vector kLargestElementsMinHeapAppraoch(vector& nums, int k) { + priority_queue, greater> minHeap; + for (int i = 0; i < k; i++) { + minHeap.push(nums[i]); + } + for (int i = k; i < nums.size(); i++) { + minHeap.push(nums[i]); + if (minHeap.size() > k) { + minHeap.pop(); + } + } + vector result; + while (!minHeap.empty()) { + result.push_back(minHeap.top()); + minHeap.pop(); + } + return result; + } + + // Top K Frequent Elements using Sorting + vector topKFrequentElementsSortingApproach(vector& nums, int k) { + unordered_map frequencyMap; + for (int num : nums) { + frequencyMap[num]++; + } + + vector> freqVec(frequencyMap.begin(), frequencyMap.end()); + sort(freqVec.begin(), freqVec.end(), [](pair& a, pair& b) { + return b.second < a.second; + }); + + vector result; + for (int i = 0; i < k; i++) { + result.push_back(freqVec[i].first); + } + return result; + } + + // Top K Frequent Elements using Min Heap + vector topKFrequentElementsMinHeapApproach(vector& nums, int k) { + unordered_map frequencyMap; + for (int num : nums) { + frequencyMap[num]++; + } + + priority_queue, vector>, greater>> minHeap; + for (auto& entry : frequencyMap) { + minHeap.push({entry.second, entry.first}); + if (minHeap.size() > k) { + minHeap.pop(); + } + } + + vector result; + while (!minHeap.empty()) { + result.push_back(minHeap.top().second); + minHeap.pop(); + } + return result; + } + + // K Closest Points to Origin using Max Heap + int getDistance(vector& point) { + return point[0] * point[0] + point[1] * point[1]; + } + + vector> kClosestPointsToOriginMaxHeapApproach(vector>& points, int k) { + priority_queue>> maxHeap; + for (vector& point : points) { + maxHeap.push({getDistance(point), point}); + if (maxHeap.size() > k) { + maxHeap.pop(); + } + } + + vector> result; + while (!maxHeap.empty()) { + result.push_back(maxHeap.top().second); + maxHeap.pop(); + } + return result; + } +}; \ No newline at end of file diff --git a/patterns/go/top_k_elements.go b/patterns/go/top_k_elements.go new file mode 100644 index 0000000..3a8d0f4 --- /dev/null +++ b/patterns/go/top_k_elements.go @@ -0,0 +1,96 @@ +package main + +import ( + "container/heap" + "sort" +) + +// ********** K Largest Elements ********** +// K Largest Elements using Sorting +func kLargestElementsSortingApproach(nums []int, k int) []int { + sort.Sort(sort.Reverse(sort.IntSlice(nums))) + return nums[:k] +} + +// K Largest Elements using Max Heap +func kLargestElementsMaxHeapApproach(nums []int, k int) []int { + h := &MaxHeap{} + heap.Init(h) + for _, num := range nums { + heap.Push(h, num) + } + result := make([]int, k) + for i := 0; i < k; i++ { + result[i] = heap.Pop(h).(int) + } + return result +} + +// K Largest Elements using Min Heap +func kLargestElementsMinHeapApproach(nums []int, k int) []int { + h := &MinHeap{} + heap.Init(h) + for i := 0; i < k; i++ { + heap.Push(h, nums[i]) + } + for i := k; i < len(nums); i++ { + heap.Push(h, nums[i]) + if h.Len() > k { + heap.Pop(h) + } + } + result := make([]int, k) + for i := 0; i < k; i++ { + result[i] = heap.Pop(h).(int) + } + return result +} + +// ********** Helper Structures ********** + +type MaxHeap []int +type MinHeap []int + +func (h MaxHeap) Len() int { return len(h) } +func (h MaxHeap) Less(i, j int) bool { return h[i] > h[j] } // Max heap +func (h MaxHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } +func (h *MaxHeap) Push(x interface{}) { *h = append(*h, x.(int)) } +func (h *MaxHeap) Pop() interface{} { + old := *h + n := len(old) + x := old[n-1] + *h = old[0 : n-1] + return x +} + +func (h MinHeap) Len() int { return len(h) } +func (h MinHeap) Less(i, j int) bool { return h[i] < h[j] } // Min heap +func (h MinHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } +func (h *MinHeap) Push(x interface{}) { *h = append(*h, x.(int)) } +func (h *MinHeap) Pop() interface{} { + old := *h + n := len(old) + x := old[n-1] + *h = old[0 : n-1] + return x +} + +// ********** Main ********** + +func main() { + // Example test cases + nums := []int{3, 2, 1, 5, 6, 4} + k := 2 + + // Sorting Approach + result := kLargestElementsSortingApproach(nums, k) + fmt.Println("K Largest Elements (Sorting Approach):", result) + + // Max Heap Approach + result = kLargestElementsMaxHeapApproach(nums, k) + fmt.Println("K Largest Elements (Max Heap Approach):", result) + + // Min Heap Approach + result = kLargestElementsMinHeapApproach(nums, k) + fmt.Println("K Largest Elements (Min Heap Approach):", result) +} \ No newline at end of file diff --git a/patterns/java/TopKElements.java b/patterns/java/TopKElements.java new file mode 100644 index 0000000..c84c391 --- /dev/null +++ b/patterns/java/TopKElements.java @@ -0,0 +1,149 @@ +package patterns.java; + +import patterns.java.FastAndSlowPointers.ListNode; +import java.util.*; + +public class TopKElements { + + /* + * ********** K Largest Elements ********** + */ + + public int[] kLargestElementsSortingAppraoch(int[] nums, int k) { + // Step 1: Sort the array in descending order + Integer[] numsArray = Arrays.stream(nums).boxed().toArray(Integer[]::new); + Arrays.sort(numsArray, Collections.reverseOrder()); + + // Step 2: Extract the first K elements + int[] result = new int[k]; + for (int i = 0; i < k; i++) { + result[i] = numsArray[i]; + } + return result; + } + + public int[] kLargestElementsMaxHeapAppraoch(int[] nums, int k) { + // Max heap + PriorityQueue maxHeap = new PriorityQueue<>(Collections.reverseOrder()); + + // Add all numbers to the max heap + for (int num : nums) { + maxHeap.add(num); + } + + // Extract the top K largest elements + int[] result = new int[k]; + for (int i = 0; i < k; i++) { + result[i] = maxHeap.poll(); // Extracts the largest element + } + return result; + } + + public int[] kLargestElementsMinHeapAppraoch(int[] nums, int k) { + // Min heap + PriorityQueue minHeap = new PriorityQueue<>(); + + // Add first K elements into the min heap + for(int i = 0; i < k; i++) { + minHeap.add(nums[i]); + } + + // Process the remaining elements + for (int i = k; i < nums.length; i++) { + minHeap.add(nums[i]); + if (minHeap.size() > k) { + minHeap.poll(); + } + } + + // Extract the top K largest elements from the min heap + int[] result = new int[k]; + for (int i = 0; i < k; i++) { + result[i] = minHeap.poll(); + } + return result; + } + + /* + * ********** LeetCode 347 - Top K Frequent Elements (https://leetcode.com/problems/top-k-frequent-elements/description/) ********** + */ + + public int[] topKFrequentElementsSortingApproach(int[] nums, int k) { + // Step 1: Build the frequency map + Map frequencyMap = new HashMap<>(); + for (int num : nums) { + frequencyMap.put(num, frequencyMap.getOrDefault(num, 0) + 1); + } + + // Step 2: Sort the entries by frequency in descending order + List> entryList = new ArrayList<>(frequencyMap.entrySet()); + entryList.sort((a, b) -> b.getValue() - a.getValue()); + + // Step 3: Extract the top K elements + int[] result = new int[k]; + for (int i = 0; i < k; i++) { + result[i] = entryList.get(i).getKey(); + } + + return result; + } + + public int[] topKFrequentElementsMinHeapApproach(int[] nums, int k) { + // Step 1: Build the frequency map + Map frequencyMap = new HashMap<>(); + for (int num : nums) { + frequencyMap.put(num, frequencyMap.getOrDefault(num, 0) + 1); + } + + // Step 2: Use a min heap to keep track of the top K elements + PriorityQueue> minHeap = new PriorityQueue<>( + (a, b) -> a.getValue() - b.getValue() // Compare by frequency + ); + + // Step 3: Add each entry to the heap, and maintain size K + for (Map.Entry entry : frequencyMap.entrySet()) { + minHeap.add(entry); + if (minHeap.size() > k) { + minHeap.poll(); // Remove the element with the lowest frequency + } + } + + // Step 4: Extract the elements from the heap + int[] result = new int[k]; + for (int i = 0; i < k; i++) { + result[i] = minHeap.poll().getKey(); // Get the element (key) from the heap + } + + return result; + } + + /* + * ********** LeetCode 973 - K Closest Points to Origin (https://leetcode.com/problems/k-closest-points-to-origin/description/) ********** + */ + private int getDistance(int[] point) { + return point[0] * point[0] + point[1] * point[1]; // Squared distance to avoid floating-point operations + } + + public int[][] kClosestPointsToOriginMaxHeapApproach(int[][] points, int k) { + // Max heap with custom comparator to compare by distance + PriorityQueue maxHeap = new PriorityQueue<>((a, b) -> getDistance(b) - getDistance(a)); + + // Iterate through all points + for (int[] point : points) { + maxHeap.add(point); // Add the current point to the heap + + // If the heap exceeds size K, remove the farthest point + if (maxHeap.size() > k) { + maxHeap.poll(); // Remove the point with the largest distance (root of max heap) + } + } + + // Convert the remaining points in the heap to the result array + int[][] result = new int[k][2]; + for (int i = 0; i < k; i++) { + result[i] = maxHeap.poll(); + } + + return result; + } +} \ No newline at end of file diff --git a/patterns/javascript/top_k_elements.js b/patterns/javascript/top_k_elements.js new file mode 100644 index 0000000..c8ab028 --- /dev/null +++ b/patterns/javascript/top_k_elements.js @@ -0,0 +1,88 @@ +class TopKElements { + + // K Largest Elements using Sorting + kLargestElementsSortingApproach(nums, k) { + nums.sort((a, b) => b - a); + return nums.slice(0, k); + } + + // K Largest Elements using Max Heap + kLargestElementsMaxHeapApproach(nums, k) { + const maxHeap = new MaxPriorityQueue({ priority: x => x }); + for (const num of nums) { + maxHeap.enqueue(num); + } + const result = []; + for (let i = 0; i < k; i++) { + result.push(maxHeap.dequeue().element); + } + return result; + } + + // K Largest Elements using Min Heap + kLargestElementsMinHeapApproach(nums, k) { + const minHeap = new MinPriorityQueue({ priority: x => x }); + for (let i = 0; i < k; i++) { + minHeap.enqueue(nums[i]); + } + for (let i = k; i < nums.length; i++) { + minHeap.enqueue(nums[i]); + if (minHeap.size() > k) { + minHeap.dequeue(); + } + } + const result = []; + for (let i = 0; i < k; i++) { + result.push(minHeap.dequeue().element); + } + return result; + } + + // Top K Frequent Elements using Sorting + topKFrequentElementsSortingApproach(nums, k) { + const frequencyMap = new Map(); + nums.forEach(num => frequencyMap.set(num, (frequencyMap.get(num) || 0) + 1)); + return Array.from(frequencyMap) + .sort((a, b) => b[1] - a[1]) + .slice(0, k) + .map(entry => entry[0]); + } + + // Top K Frequent Elements using Min Heap + topKFrequentElementsMinHeapApproach(nums, k) { + const frequencyMap = new Map(); + nums.forEach(num => frequencyMap.set(num, (frequencyMap.get(num) || 0) + 1)); + const minHeap = new MinPriorityQueue({ priority: x => x[1] }); + frequencyMap.forEach((value, key) => { + minHeap.enqueue([key, value]); + if (minHeap.size() > k) { + minHeap.dequeue(); + } + }); + const result = []; + for (let i = 0; i < k; i++) { + result.push(minHeap.dequeue().element[0]); + } + return result; + } + + // K Closest Points to Origin using Max Heap + getDistance(point) { + return point[0] ** 2 + point[1] ** 2; + } + + kClosestPointsToOriginMaxHeapApproach(points, k) { + const maxHeap = new MaxPriorityQueue({ priority: point => -this.getDistance(point) }); + points.forEach(point => { + maxHeap.enqueue(point); + if (maxHeap.size() > k) { + maxHeap.dequeue(); + } + }); + const result = []; + for (let i = 0; i < k; i++) { + result.push(maxHeap.dequeue().element); + } + return result; + } +} \ No newline at end of file diff --git a/patterns/python/top_k_elements.py b/patterns/python/top_k_elements.py new file mode 100644 index 0000000..cf234c1 --- /dev/null +++ b/patterns/python/top_k_elements.py @@ -0,0 +1,49 @@ +import heapq +from collections import Counter + +class TopKElements: + + # K Largest Elements using Sorting + def k_largest_elements_sorting_approach(self, nums, k): + return sorted(nums, reverse=True)[:k] + + # K Largest Elements using Max Heap + def k_largest_elements_max_heap_approach(self, nums, k): + return heapq.nlargest(k, nums) + + # K Largest Elements using Min Heap + def k_largest_elements_min_heap_approach(self, nums, k): + min_heap = nums[:k] + heapq.heapify(min_heap) + for num in nums[k:]: + heapq.heappush(min_heap, num) + if len(min_heap) > k: + heapq.heappop(min_heap) + return [heapq.heappop(min_heap) for _ in range(k)][::-1] + + # Top K Frequent Elements using Sorting + def top_k_frequent_elements_sorting_approach(self, nums, k): + count = Counter(nums) + return [num for num, freq in count.most_common(k)] + + # Top K Frequent Elements using Min Heap + def top_k_frequent_elements_min_heap_approach(self, nums, k): + count = Counter(nums) + min_heap = [] + for num, freq in count.items(): + heapq.heappush(min_heap, (freq, num)) + if len(min_heap) > k: + heapq.heappop(min_heap) + return [heapq.heappop(min_heap)[1] for _ in range(k)][::-1] + + # K Closest Points to Origin using Max Heap + def get_distance(self, point): + return point[0] ** 2 + point[1] ** 2 + + def k_closest_points_to_origin_max_heap_approach(self, points, k): + max_heap = [] + for point in points: + heapq.heappush(max_heap, (-self.get_distance(point), point)) + if len(max_heap) > k: + heapq.heappop(max_heap) + return [heapq.heappop(max_heap)[1] for _ in range(k)][::-1] \ No newline at end of file diff --git a/patterns/typescript/top_k_elements.ts b/patterns/typescript/top_k_elements.ts new file mode 100644 index 0000000..32ff24e --- /dev/null +++ b/patterns/typescript/top_k_elements.ts @@ -0,0 +1,88 @@ +class TopKElements { + + // K Largest Elements using Sorting + kLargestElementsSortingApproach(nums: number[], k: number): number[] { + nums.sort((a, b) => b - a); + return nums.slice(0, k); + } + + // K Largest Elements using Max Heap + kLargestElementsMaxHeapApproach(nums: number[], k: number): number[] { + const maxHeap = new MaxPriorityQueue({ priority: (x: number) => x }); + for (const num of nums) { + maxHeap.enqueue(num); + } + const result: number[] = []; + for (let i = 0; i < k; i++) { + result.push(maxHeap.dequeue().element); + } + return result; + } + + // K Largest Elements using Min Heap + kLargestElementsMinHeapApproach(nums: number[], k: number): number[] { + const minHeap = new MinPriorityQueue({ priority: (x: number) => x }); + for (let i = 0; i < k; i++) { + minHeap.enqueue(nums[i]); + } + for (let i = k; i < nums.length; i++) { + minHeap.enqueue(nums[i]); + if (minHeap.size() > k) { + minHeap.dequeue(); + } + } + const result: number[] = []; + for (let i = 0; i < k; i++) { + result.push(minHeap.dequeue().element); + } + return result; + } + + // Top K Frequent Elements using Sorting + topKFrequentElementsSortingApproach(nums: number[], k: number): number[] { + const frequencyMap = new Map(); + nums.forEach(num => frequencyMap.set(num, (frequencyMap.get(num) || 0) + 1)); + return Array.from(frequencyMap) + .sort((a, b) => b[1] - a[1]) + .slice(0, k) + .map(entry => entry[0]); + } + + // Top K Frequent Elements using Min Heap + topKFrequentElementsMinHeapApproach(nums: number[], k: number): number[] { + const frequencyMap = new Map(); + nums.forEach(num => frequencyMap.set(num, (frequencyMap.get(num) || 0) + 1)); + const minHeap = new MinPriorityQueue({ priority: (x: [number, number]) => x[1] }); + frequencyMap.forEach((value, key) => { + minHeap.enqueue([key, value]); + if (minHeap.size() > k) { + minHeap.dequeue(); + } + }); + const result: number[] = []; + for (let i = 0; i < k; i++) { + result.push(minHeap.dequeue().element[0]); + } + return result; + } + + // K Closest Points to Origin using Max Heap + getDistance(point: number[]): number { + return point[0] ** 2 + point[1] ** 2; + } + + kClosestPointsToOriginMaxHeapApproach(points: number[][], k: number): number[][] { + const maxHeap = new MaxPriorityQueue({ priority: (point: number[]) => -this.getDistance(point) }); + points.forEach(point => { + maxHeap.enqueue(point); + if (maxHeap.size() > k) { + maxHeap.dequeue(); + } + }); + const result: number[][] = []; + for (let i = 0; i < k; i++) { + result.push(maxHeap.dequeue().element); + } + return result; + } +} \ No newline at end of file From 5951b659dc8b8be27500428e730704c938aaaf90 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Thu, 24 Oct 2024 08:35:05 +0530 Subject: [PATCH 05/25] Update links --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 99444f5..863f6df 100644 --- a/README.md +++ b/README.md @@ -80,8 +80,8 @@ This repository contains awesome LeetCode resources to learn Data Structures and - [Coursera - Algorithms, Part 2](https://www.coursera.org/learn/algorithms-part2) ## 📚 Books -- [Data Structures And Algorithms Made Easy](https://www.amazon.com/Data-Structures-Algorithms-Made-Easy-ebook/dp/B0CBW278NC/) -- [Cracking the Coding Interview](https://www.amazon.com/Cracking-Coding-Interview-Programming-Questions/dp/0984782850/) +- [Data Structures And Algorithms Made Easy](https://amzn.to/40bsEUF) +- [Cracking the Coding Interview](https://amzn.to/4e4HNdE) ## 🔎 Visualization - [VisuAlgo](https://visualgo.net/en) From 286d2dc8e978447d65a514bba61160de2764cae1 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Mon, 28 Oct 2024 19:21:16 +0530 Subject: [PATCH 06/25] add level order traversal code --- patterns/c#/LevelOrderTraversal.cs | 30 ++++++++++++++ patterns/c++/LevelOrderTraversal.cpp | 32 +++++++++++++++ patterns/go/level_order_traversal.go | 39 +++++++++++++++++++ patterns/java/LevelOrderTraversal.java | 33 ++++++++++++++++ patterns/javascript/levelOrderTraversal.js | 24 ++++++++++++ .../{top_k_elements.js => topKElements.js} | 0 patterns/python/level_order_traversal.py | 25 ++++++++++++ patterns/typescript/levelOrderTraversal.ts | 28 +++++++++++++ .../{top_k_elements.ts => topKElements.ts} | 0 9 files changed, 211 insertions(+) create mode 100644 patterns/c#/LevelOrderTraversal.cs create mode 100644 patterns/c++/LevelOrderTraversal.cpp create mode 100644 patterns/go/level_order_traversal.go create mode 100644 patterns/java/LevelOrderTraversal.java create mode 100644 patterns/javascript/levelOrderTraversal.js rename patterns/javascript/{top_k_elements.js => topKElements.js} (100%) create mode 100644 patterns/python/level_order_traversal.py create mode 100644 patterns/typescript/levelOrderTraversal.ts rename patterns/typescript/{top_k_elements.ts => topKElements.ts} (100%) diff --git a/patterns/c#/LevelOrderTraversal.cs b/patterns/c#/LevelOrderTraversal.cs new file mode 100644 index 0000000..05b2a53 --- /dev/null +++ b/patterns/c#/LevelOrderTraversal.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; + +public class TreeNode { + public int val; + public TreeNode left; + public TreeNode right; + + public TreeNode(int x) { + val = x; + } +} + +public class LevelOrderTraversal { + public void LevelOrder(TreeNode root) { + if (root == null) return; + + Queue queue = new Queue(); + queue.Enqueue(root); + + while (queue.Count > 0) { + TreeNode node = queue.Dequeue(); + Console.Write(node.val + " "); // Process the node by printing its value + + // Add the left and right children to the queue, if they exist + if (node.left != null) queue.Enqueue(node.left); + if (node.right != null) queue.Enqueue(node.right); + } + } +} \ No newline at end of file diff --git a/patterns/c++/LevelOrderTraversal.cpp b/patterns/c++/LevelOrderTraversal.cpp new file mode 100644 index 0000000..d32a116 --- /dev/null +++ b/patterns/c++/LevelOrderTraversal.cpp @@ -0,0 +1,32 @@ +#include +#include +using namespace std; + +// Definition for a binary tree node. +struct TreeNode { + int val; + TreeNode* left; + TreeNode* right; + + TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} +}; + +class LevelOrderTraversal { +public: + void levelOrder(TreeNode* root) { + if (root == nullptr) return; + + queue q; + q.push(root); + + while (!q.empty()) { + TreeNode* node = q.front(); + q.pop(); + cout << node->val << " "; // Process the node by printing its value + + // Add the left and right children to the queue, if they exist + if (node->left != nullptr) q.push(node->left); + if (node->right != nullptr) q.push(node->right); + } + } +}; \ No newline at end of file diff --git a/patterns/go/level_order_traversal.go b/patterns/go/level_order_traversal.go new file mode 100644 index 0000000..04e388e --- /dev/null +++ b/patterns/go/level_order_traversal.go @@ -0,0 +1,39 @@ +package main + +import "fmt" + +// Definition for a binary tree node. +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func levelOrder(root *TreeNode) { + if root == nil { + return + } + + queue := []*TreeNode{root} + + for len(queue) > 0 { + node := queue[0] + queue = queue[1:] + fmt.Print(node.Val, " ") // Process the node by printing its value + + // Add the left and right children to the queue, if they exist + if node.Left != nil { + queue = append(queue, node.Left) + } + if node.Right != nil { + queue = append(queue, node.Right) + } +} + +func main() { + // Example usage + root := &TreeNode{Val: 1} + root.Left = &TreeNode{Val: 2} + root.Right = &TreeNode{Val: 3} + levelOrder(root) // Output: 1 2 3 +} \ No newline at end of file diff --git a/patterns/java/LevelOrderTraversal.java b/patterns/java/LevelOrderTraversal.java new file mode 100644 index 0000000..ac56f0f --- /dev/null +++ b/patterns/java/LevelOrderTraversal.java @@ -0,0 +1,33 @@ +package patterns.java; + +import java.util.LinkedList; +import java.util.Queue; + +// Definition for a binary tree node. +class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } +} + +public class LevelOrderTraversal { + public void levelOrder(TreeNode root) { + if (root == null) return; + + Queue queue = new LinkedList<>(); + queue.add(root); + + while (!queue.isEmpty()) { + TreeNode node = queue.poll(); + System.out.print(node.val + " "); // Process the node by printing its value + + // Add the left and right children to the queue, if they exist + if (node.left != null) queue.add(node.left); + if (node.right != null) queue.add(node.right); + } + } +} diff --git a/patterns/javascript/levelOrderTraversal.js b/patterns/javascript/levelOrderTraversal.js new file mode 100644 index 0000000..c65bab9 --- /dev/null +++ b/patterns/javascript/levelOrderTraversal.js @@ -0,0 +1,24 @@ +// Definition for a binary tree node. +class TreeNode { + constructor(val) { + this.val = val; + this.left = this.right = null; + } +} + +class LevelOrderTraversal { + levelOrder(root) { + if (root === null) return; + + const queue = [root]; + + while (queue.length > 0) { + const node = queue.shift(); + console.log(node.val); // Process the node by printing its value + + // Add the left and right children to the queue, if they exist + if (node.left !== null) queue.push(node.left); + if (node.right !== null) queue.push(node.right); + } + } +} \ No newline at end of file diff --git a/patterns/javascript/top_k_elements.js b/patterns/javascript/topKElements.js similarity index 100% rename from patterns/javascript/top_k_elements.js rename to patterns/javascript/topKElements.js diff --git a/patterns/python/level_order_traversal.py b/patterns/python/level_order_traversal.py new file mode 100644 index 0000000..c52fc99 --- /dev/null +++ b/patterns/python/level_order_traversal.py @@ -0,0 +1,25 @@ +from collections import deque + +# Definition for a binary tree node. +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None + +class LevelOrderTraversal: + def level_order(self, root): + if root is None: + return + + queue = deque([root]) + + while queue: + node = queue.popleft() + print(node.val, end=" ") # Process the node by printing its value + + # Add the left and right children to the queue, if they exist + if node.left: + queue.append(node.left) + if node.right: + queue.append(node.right) \ No newline at end of file diff --git a/patterns/typescript/levelOrderTraversal.ts b/patterns/typescript/levelOrderTraversal.ts new file mode 100644 index 0000000..dfbbcb3 --- /dev/null +++ b/patterns/typescript/levelOrderTraversal.ts @@ -0,0 +1,28 @@ +// Definition for a binary tree node. +class BinaryTreeNode { + val: number; + left: TreeNode | null; + right: TreeNode | null; + + constructor(val: number) { + this.val = val; + this.left = this.right = null; + } +} + +class BinaryTreeLevelOrderTraversal { + levelOrder(root: BinaryTreeNode | null): void { + if (root === null) return; + + const queue: BinaryTreeNode[] = [root]; + + while (queue.length > 0) { + const node = queue.shift()!; + console.log(node.val); // Process the node by printing its value + + // Add the left and right children to the queue, if they exist + if (node.left !== null) queue.push(node.left); + if (node.right !== null) queue.push(node.right); + } + } +} \ No newline at end of file diff --git a/patterns/typescript/top_k_elements.ts b/patterns/typescript/topKElements.ts similarity index 100% rename from patterns/typescript/top_k_elements.ts rename to patterns/typescript/topKElements.ts From bdc2673a6905d26b936f825a68031068a1810932 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Mon, 28 Oct 2024 22:24:23 +0530 Subject: [PATCH 07/25] Update some of the pattern links to youtube videos --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 863f6df..43b7a89 100644 --- a/README.md +++ b/README.md @@ -40,11 +40,12 @@ This repository contains awesome LeetCode resources to learn Data Structures and ## 🚀 Patterns - [15 Leetcode Patterns](https://blog.algomaster.io/p/15-leetcode-patterns) - [20 DP Patterns](https://blog.algomaster.io/p/20-patterns-to-master-dynamic-programming) -- [Prefix Sum Pattern](https://blog.algomaster.io/p/f96dd3de-c89c-428e-a88d-b1f751a42a57) +- [Prefix Sum Pattern](https://www.youtube.com/watch?v=yuws7YK0Yng) +- [Top 'K' Elements Pattern](https://www.youtube.com/watch?v=6_v6OoxvMOE) +- [Fast and Slow Pointers Pattern](https://www.youtube.com/watch?v=b139yf7Ik-E) - [Two Pointers Pattern](https://blog.algomaster.io/p/69025a2e-b0d5-4705-8507-bba16c2691f1) - [Linked List In-place Reversal Pattern](https://blog.algomaster.io/p/7dcce8e9-beee-4fef-8874-7aae025031b1) - [Sliding Window Pattern](https://blog.algomaster.io/p/f4412a17-7a3a-4d0b-8e39-9ea8f429bf7c) -- [Top 'K' Elements Pattern](https://blog.algomaster.io/p/322aac40-c4d0-4e54-980d-b22d9eeebca6) - [Monotonic Stack Pattern](https://blog.algomaster.io/p/5dabff21-11f4-470d-8e38-76ff07c63fdf) - [Overlapping Intervals Pattern](https://blog.algomaster.io/p/812e72f7-eced-4256-a4c1-00606ae50679) - [Backtracking Pattern](https://blog.algomaster.io/p/81d42ca2-600c-4252-aa33-a56462090048) From 607e9df4344e5d6765b3454c51ef0d11a190f78c Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Sun, 24 Nov 2024 18:59:51 +0530 Subject: [PATCH 08/25] Add AlgoMaster 200 list --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 43b7a89..3beeaaa 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,7 @@ This repository contains awesome LeetCode resources to learn Data Structures and - [LeetCode VS Code Extension](https://marketplace.visualstudio.com/items?itemName=LeetCode.vscode-leetcode): Solve LeetCode problems in VS Code. ## ✅ Curated Problems +- [AlgoMaster 200](https://algomaster.io/practice/dsa-patterns) - [Blind 75](https://leetcode.com/discuss/general-discussion/460599/blind-75-leetcode-questions) - [Leetcode Top 100 Liked](https://leetcode.com/studyplan/top-100-liked/) - [Leetcode Top Interview 150](https://leetcode.com/studyplan/top-interview-150/) From 1da1cb4175cbda83f03c35f375c3c37429668299 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Sun, 22 Dec 2024 16:47:34 +0530 Subject: [PATCH 09/25] Update AlgoMaster Link --- README.md | 81 ++++++------------------------------------------------- 1 file changed, 8 insertions(+), 73 deletions(-) diff --git a/README.md b/README.md index 3beeaaa..098544f 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ This repository contains awesome LeetCode resources to learn Data Structures and Algorithms (DSA) and prepare for Coding interviews. +If you want to practice curated list of LeetCode problems organized by patterns, checkout [AlgoMaster.io](https://algomaster.io) + ## 💡 Tips - [How to Start LeetCode](https://www.youtube.com/watch?v=Nx4bvwU0DqE) - [How I Mastered DSA](https://blog.algomaster.io/p/how-i-mastered-data-structures-and-algorithms) @@ -84,6 +86,12 @@ This repository contains awesome LeetCode resources to learn Data Structures and - [Data Structures And Algorithms Made Easy](https://amzn.to/40bsEUF) - [Cracking the Coding Interview](https://amzn.to/4e4HNdE) +## ✅ Curated Problems +- [AlgoMaster 300](https://algomaster.io/practice/dsa-patterns) +- [Blind 75](https://leetcode.com/discuss/general-discussion/460599/blind-75-leetcode-questions) +- [Leetcode Top 100 Liked](https://leetcode.com/studyplan/top-100-liked/) +- [Leetcode Top Interview 150](https://leetcode.com/studyplan/top-interview-150/) + ## 🔎 Visualization - [VisuAlgo](https://visualgo.net/en) - [Algo-lens: Visualize leetcode problems](https://github.com/jaroslaw-weber/algo-lens) @@ -95,77 +103,4 @@ This repository contains awesome LeetCode resources to learn Data Structures and - [LeetHub v2](https://chromewebstore.google.com/detail/leethub-v2/mhanfgfagplhgemhjfeolkkdidbakocm?hl=en): Automatically integrate your Leetcode & GeeksforGeeks submissions to GitHub. - [LeetCode VS Code Extension](https://marketplace.visualstudio.com/items?itemName=LeetCode.vscode-leetcode): Solve LeetCode problems in VS Code. -## ✅ Curated Problems -- [AlgoMaster 200](https://algomaster.io/practice/dsa-patterns) -- [Blind 75](https://leetcode.com/discuss/general-discussion/460599/blind-75-leetcode-questions) -- [Leetcode Top 100 Liked](https://leetcode.com/studyplan/top-100-liked/) -- [Leetcode Top Interview 150](https://leetcode.com/studyplan/top-interview-150/) - -## 💻 Must-Do Problems (Topic Wise) -### Linked List -- [Reverse Linked List](https://leetcode.com/problems/reverse-linked-list/description/) -- [Linked List Cycle](https://leetcode.com/problems/linked-list-cycle/description/) -- [Merge Two Sorted Lists](https://leetcode.com/problems/merge-two-sorted-lists/description/) -- [Intersection of Two Linked Lists](https://leetcode.com/problems/intersection-of-two-linked-lists/description/) -- [Remove Nth Node From End of List](https://leetcode.com/problems/remove-nth-node-from-end-of-list/description/) -- [Add Two Numbers](https://leetcode.com/problems/add-two-numbers/description/) -- [Copy List with Random Pointer](https://leetcode.com/problems/copy-list-with-random-pointer/description/) -- [Flatten a Multilevel Doubly Linked List](https://leetcode.com/problems/flatten-a-multilevel-doubly-linked-list) -- [Rotate List](https://leetcode.com/problems/rotate-list/description/) -- [Sort List](https://leetcode.com/problems/sort-list/description/) -- [Remove Duplicates from Sorted List II](https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/description/) -- [LRU Cache](https://leetcode.com/problems/lru-cache/description/) -- [Design Browser History](https://leetcode.com/problems/design-browser-history/description/) -- [Merge k Sorted Lists](https://leetcode.com/problems/merge-k-sorted-lists/description/) -- [Reverse Nodes in k-Group](https://leetcode.com/problems/reverse-nodes-in-k-group/description/) -### Binary Trees - - [Invert Binary Tree](https://leetcode.com/problems/invert-binary-tree/description/) - - [Convert Sorted Array to Binary Search Tree](https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/description/) - - [Count Complete Tree Nodes](https://leetcode.com/problems/count-complete-tree-nodes/description/) - - [All Possible Full Binary Trees](https://leetcode.com/problems/all-possible-full-binary-trees/description/) - - [Delete Leaves With a Given Value](https://leetcode.com/problems/delete-leaves-with-a-given-value/description/) - - [Binary Search Tree Iterator](https://leetcode.com/problems/binary-search-tree-iterator/description/) - - [Longest Univalue Path](https://leetcode.com/problems/longest-univalue-path/description/) - - [Delete Nodes And Return Forest](https://leetcode.com/problems/delete-nodes-and-return-forest/description/) - - [Validate Binary Search Tree](https://leetcode.com/problems/validate-binary-search-tree/description/) - - [Construct Binary Tree from Inorder and Postorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/description/) - - [All Nodes Distance K in Binary Tree](https://leetcode.com/problems/all-nodes-distance-k-in-binary-tree/description/) - - [Maximum Difference Between Node and Ancestor](https://leetcode.com/problems/maximum-difference-between-node-and-ancestor/description/) - - [Find Duplicate Subtrees](https://leetcode.com/problems/find-duplicate-subtrees/description/) - - [Flatten Binary Tree to Linked List](https://leetcode.com/problems/flatten-binary-tree-to-linked-list/description/) - - [House Robber III](https://leetcode.com/problems/house-robber-iii/description/) - - [Step-By-Step Directions From a Binary Tree Node to Another](https://leetcode.com/problems/step-by-step-directions-from-a-binary-tree-node-to-another/description/) - - [Delete Node in a BST](https://leetcode.com/problems/delete-node-in-a-bst/description/) - - [Populating Next Right Pointers in Each Node II](https://leetcode.com/problems/populating-next-right-pointers-in-each-node-ii/description/) - - [Trim a Binary Search Tree](https://leetcode.com/problems/trim-a-binary-search-tree/description/) - - [Distribute Coins in Binary Tree](https://leetcode.com/problems/distribute-coins-in-binary-tree/description/) - - [Binary Search Tree to Greater Sum Tree](https://leetcode.com/problems/binary-search-tree-to-greater-sum-tree/description/) - - [Serialize and Deserialize Binary Tree](https://leetcode.com/problems/serialize-and-deserialize-binary-tree/description/) - - [Binary Tree Cameras](https://leetcode.com/problems/binary-tree-cameras/description/) - - [Binary Tree Maximum Path Sum](https://leetcode.com/problems/binary-tree-maximum-path-sum/description/) - - [Maximum Sum BST in Binary Tree](https://leetcode.com/problems/maximum-sum-bst-in-binary-tree/description/) -### Backtracking -- [Permutations](https://leetcode.com/problems/permutations/description/) -- [Subsets](https://leetcode.com/problems/subsets/description/) -- [Generate Parentheses](https://leetcode.com/problems/generate-parentheses/description/) -- [Combination Sum](https://leetcode.com/problems/combination-sum/description/) -- [Palindrome Partitioning](https://leetcode.com/problems/palindrome-partitioning/description/) -- [Letter Combinations of a Phone Number](https://leetcode.com/problems/letter-combinations-of-a-phone-number/description/) -- [Unique Binary Search Trees II](https://leetcode.com/problems/unique-binary-search-trees-ii/description/) -- [Partition to K Equal Sum Subsets](https://leetcode.com/problems/partition-to-k-equal-sum-subsets/description/) -- [N-Queens II](https://leetcode.com/problems/n-queens-ii/description/) -- [Sudoku Solver](https://leetcode.com/problems/sudoku-solver/description/) -### Tries - - [Implement Trie (Prefix Tree)](https://leetcode.com/problems/implement-trie-prefix-tree/description/) - - [Longest Common Prefix](https://leetcode.com/problems/longest-common-prefix/description/) - - [Search Suggestions System](https://leetcode.com/problems/search-suggestions-system/description/) - - [Longest Word in Dictionary](https://leetcode.com/problems/longest-word-in-dictionary/description/) - - [Top K Frequent Words](https://leetcode.com/problems/top-k-frequent-words/description/) - - [Design Add and Search Words Data Structure](https://leetcode.com/problems/design-add-and-search-words-data-structure/description/) - - [Implement Magic Dictionary](https://leetcode.com/problems/implement-magic-dictionary/description/) - - [Replace Words](https://leetcode.com/problems/replace-words/description/) - - [Word Search II](https://leetcode.com/problems/word-search-ii/description/) - - [Stream of Characters](https://leetcode.com/problems/stream-of-characters/description/) - - Your contributions are most welcome! From a0560c429da96edd810183beac0f2b92daf87cdb Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Mon, 30 Dec 2024 16:51:47 +0530 Subject: [PATCH 10/25] add kadane algorithm --- patterns/c#/KadaneAlgorithm.cs | 14 ++++++++++++++ patterns/c++/KadaneAlgorithm.cpp | 0 patterns/go/kadane_algorithm.go | 15 +++++++++++++++ patterns/java/KadaneAlgorithm.java | 17 +++++++++++++++++ patterns/javascript/kadaneAlgorithm.js | 12 ++++++++++++ patterns/python/kadane_algorithm.py | 10 ++++++++++ patterns/typescript/kadaneAlgorithm.ts | 12 ++++++++++++ 7 files changed, 80 insertions(+) create mode 100644 patterns/c#/KadaneAlgorithm.cs create mode 100644 patterns/c++/KadaneAlgorithm.cpp create mode 100644 patterns/go/kadane_algorithm.go create mode 100644 patterns/java/KadaneAlgorithm.java create mode 100644 patterns/javascript/kadaneAlgorithm.js create mode 100644 patterns/python/kadane_algorithm.py create mode 100644 patterns/typescript/kadaneAlgorithm.ts diff --git a/patterns/c#/KadaneAlgorithm.cs b/patterns/c#/KadaneAlgorithm.cs new file mode 100644 index 0000000..f27991b --- /dev/null +++ b/patterns/c#/KadaneAlgorithm.cs @@ -0,0 +1,14 @@ +using System; + +public class KadaneAlgorithm { + public int MaxSubArray(int[] nums) { + int currentSum = nums[0]; + int maxSum = nums[0]; + + for (int i = 1; i < nums.Length; i++) { + currentSum = Math.Max(nums[i], currentSum + nums[i]); + maxSum = Math.Max(maxSum, currentSum); + } + return maxSum; + } +} \ No newline at end of file diff --git a/patterns/c++/KadaneAlgorithm.cpp b/patterns/c++/KadaneAlgorithm.cpp new file mode 100644 index 0000000..e69de29 diff --git a/patterns/go/kadane_algorithm.go b/patterns/go/kadane_algorithm.go new file mode 100644 index 0000000..4832097 --- /dev/null +++ b/patterns/go/kadane_algorithm.go @@ -0,0 +1,15 @@ +package main + +import "math" + +func maxSubArray(nums []int) int { + currentSum := nums[0] + maxSum := nums[0] + + for i := 1; i < len(nums); i++ { + currentSum = int(math.Max(float64(nums[i]), float64(currentSum+nums[i]))) + maxSum = int(math.Max(float64(maxSum), float64(currentSum))) + } + + return maxSum +} diff --git a/patterns/java/KadaneAlgorithm.java b/patterns/java/KadaneAlgorithm.java new file mode 100644 index 0000000..9e3f46b --- /dev/null +++ b/patterns/java/KadaneAlgorithm.java @@ -0,0 +1,17 @@ +package patterns.java; + +public class KadaneAlgorithm { + public int maxSubArray(int[] nums) { + int currentSum = nums[0]; // Start with the first element + int maxSum = nums[0]; // Initialize maxSum with the first element + + // Traverse the array from the second element + for (int i = 1; i < nums.length; i++) { + // If currentSum is negative, reset to current element + currentSum = Math.max(nums[i], currentSum + nums[i]); + // Update maxSum if currentSum is greater + maxSum = Math.max(maxSum, currentSum); + } + return maxSum; + } +} \ No newline at end of file diff --git a/patterns/javascript/kadaneAlgorithm.js b/patterns/javascript/kadaneAlgorithm.js new file mode 100644 index 0000000..859b036 --- /dev/null +++ b/patterns/javascript/kadaneAlgorithm.js @@ -0,0 +1,12 @@ +class KadaneAlgorithm { + maxSubArray(nums) { + let currentSum = nums[0]; + let maxSum = nums[0]; + + for (let i = 1; i < nums.length; i++) { + currentSum = Math.max(nums[i], currentSum + nums[i]); + maxSum = Math.max(maxSum, currentSum); + } + return maxSum; + } +} \ No newline at end of file diff --git a/patterns/python/kadane_algorithm.py b/patterns/python/kadane_algorithm.py new file mode 100644 index 0000000..66bdd33 --- /dev/null +++ b/patterns/python/kadane_algorithm.py @@ -0,0 +1,10 @@ +class KadaneAlgorithm: + def max_sub_array(self, nums): + current_sum = nums[0] + max_sum = nums[0] + + for i in range(1, len(nums)): + current_sum = max(nums[i], current_sum + nums[i]) + max_sum = max(max_sum, current_sum) + + return max_sum \ No newline at end of file diff --git a/patterns/typescript/kadaneAlgorithm.ts b/patterns/typescript/kadaneAlgorithm.ts new file mode 100644 index 0000000..5b91e80 --- /dev/null +++ b/patterns/typescript/kadaneAlgorithm.ts @@ -0,0 +1,12 @@ +class KadaneAlgorithm { + maxSubArray(nums: number[]): number { + let currentSum: number = nums[0]; + let maxSum: number = nums[0]; + + for (let i = 1; i < nums.length; i++) { + currentSum = Math.max(nums[i], currentSum + nums[i]); + maxSum = Math.max(maxSum, currentSum); + } + return maxSum; + } +} \ No newline at end of file From 60f6b05fd332ecfca3b8f773e40bc90aa1bf3736 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Mon, 30 Dec 2024 18:37:44 +0530 Subject: [PATCH 11/25] Add Kadane's algorithm --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 098544f..c5b920b 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,7 @@ If you want to practice curated list of LeetCode problems organized by patterns, - [Prefix Sum Pattern](https://www.youtube.com/watch?v=yuws7YK0Yng) - [Top 'K' Elements Pattern](https://www.youtube.com/watch?v=6_v6OoxvMOE) - [Fast and Slow Pointers Pattern](https://www.youtube.com/watch?v=b139yf7Ik-E) +- [Kadane's Algorithm](https://www.youtube.com/watch?v=NUWAXbSlsws) - [Two Pointers Pattern](https://blog.algomaster.io/p/69025a2e-b0d5-4705-8507-bba16c2691f1) - [Linked List In-place Reversal Pattern](https://blog.algomaster.io/p/7dcce8e9-beee-4fef-8874-7aae025031b1) - [Sliding Window Pattern](https://blog.algomaster.io/p/f4412a17-7a3a-4d0b-8e39-9ea8f429bf7c) From 07bff6b32b8c46f38cf803c0c96416b8b97c19f5 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Mon, 30 Dec 2024 22:35:33 +0530 Subject: [PATCH 12/25] add algomaster leetcode pattern playlist link --- README.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c5b920b..78ca9c5 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,14 @@ If you want to practice curated list of LeetCode problems organized by patterns, - [Dynamic Programming Patterns](https://leetcode.com/discuss/study-guide/458695/Dynamic-Programming-Patterns) - [Stock Series Patterns](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/solutions/108870/most-consistent-ways-of-dealing-with-the-series-of-stock-problems/) +## ✅ Curated Problems +- [AlgoMaster 300](https://algomaster.io/practice/dsa-patterns) +- [Blind 75](https://leetcode.com/discuss/general-discussion/460599/blind-75-leetcode-questions) +- [Leetcode Top 100 Liked](https://leetcode.com/studyplan/top-100-liked/) +- [Leetcode Top Interview 150](https://leetcode.com/studyplan/top-interview-150/) + ## 📺 YouTube Playlist +- [AlgoMaster LeetCode Pattern Playlist](https://www.youtube.com/playlist?list=PLK63NuByH5o-tqaMUHRA4r8ObRW7PWz45) - [Abdul Bari's Algorithms Playlist](https://www.youtube.com/playlist?list=PLDN4rrl48XKpZkf03iYFl-O29szjTrs_O) - [William Fiset's Data Structure Playlist](https://www.youtube.com/playlist?list=PLDV1Zeh2NRsB6SWUrDFW2RmDotAfPbeHu) - [William Fiset's Graphs Playlist](https://www.youtube.com/playlist?list=PLDV1Zeh2NRsDGO4--qE8yH72HFL1Km93P) @@ -87,11 +94,8 @@ If you want to practice curated list of LeetCode problems organized by patterns, - [Data Structures And Algorithms Made Easy](https://amzn.to/40bsEUF) - [Cracking the Coding Interview](https://amzn.to/4e4HNdE) -## ✅ Curated Problems -- [AlgoMaster 300](https://algomaster.io/practice/dsa-patterns) -- [Blind 75](https://leetcode.com/discuss/general-discussion/460599/blind-75-leetcode-questions) -- [Leetcode Top 100 Liked](https://leetcode.com/studyplan/top-100-liked/) -- [Leetcode Top Interview 150](https://leetcode.com/studyplan/top-interview-150/) +## 📩 Newsletter +- [AlgoMaster Newsletter](https://blog.algomaster.io/) ## 🔎 Visualization - [VisuAlgo](https://visualgo.net/en) From 33287c903dfd8918ef4c68ba989924a2c9d9c87d Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Mon, 30 Dec 2024 22:36:45 +0530 Subject: [PATCH 13/25] update book links --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 78ca9c5..408522f 100644 --- a/README.md +++ b/README.md @@ -91,8 +91,8 @@ If you want to practice curated list of LeetCode problems organized by patterns, - [Coursera - Algorithms, Part 2](https://www.coursera.org/learn/algorithms-part2) ## 📚 Books -- [Data Structures And Algorithms Made Easy](https://amzn.to/40bsEUF) -- [Cracking the Coding Interview](https://amzn.to/4e4HNdE) +- [Data Structures And Algorithms Made Easy](https://www.amazon.in/dp/B08CMLS7LZ) +- [Cracking the Coding Interview](https://www.amazon.in/dp/0984782850) ## 📩 Newsletter - [AlgoMaster Newsletter](https://blog.algomaster.io/) From ecae4b3b59dd33aa10e6e0a8099757ec0490480a Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Tue, 31 Dec 2024 00:28:15 +0530 Subject: [PATCH 14/25] add reverse linked list code --- patterns/c#/ReverseList.cs | 23 +++++++++++++++++++++++ patterns/c++/ReverseList.cpp | 18 ++++++++++++++++++ patterns/go/reverse_list.go | 19 +++++++++++++++++++ patterns/java/ReverseLinkedList.java | 20 ++++++++++++++++++++ patterns/javascript/reverseList.js | 19 +++++++++++++++++++ patterns/python/reverse_list.py | 16 ++++++++++++++++ patterns/typescript/reverseList.ts | 22 ++++++++++++++++++++++ 7 files changed, 137 insertions(+) create mode 100644 patterns/c#/ReverseList.cs create mode 100644 patterns/c++/ReverseList.cpp create mode 100644 patterns/go/reverse_list.go create mode 100644 patterns/java/ReverseLinkedList.java create mode 100644 patterns/javascript/reverseList.js create mode 100644 patterns/python/reverse_list.py create mode 100644 patterns/typescript/reverseList.ts diff --git a/patterns/c#/ReverseList.cs b/patterns/c#/ReverseList.cs new file mode 100644 index 0000000..1dd3572 --- /dev/null +++ b/patterns/c#/ReverseList.cs @@ -0,0 +1,23 @@ +public class ListNode { + public int val; + public ListNode next; + public ListNode(int val = 0, ListNode next = null) { + this.val = val; + this.next = next; + } +} + +public class Solution { + public ListNode ReverseList(ListNode head) { + ListNode prev = null; + ListNode curr = head; + + while (curr != null) { + ListNode next = curr.next; + curr.next = prev; + prev = curr; + curr = next; + } + return prev; + } +} \ No newline at end of file diff --git a/patterns/c++/ReverseList.cpp b/patterns/c++/ReverseList.cpp new file mode 100644 index 0000000..1740054 --- /dev/null +++ b/patterns/c++/ReverseList.cpp @@ -0,0 +1,18 @@ +struct ListNode { + int val; + ListNode* next; + ListNode(int x) : val(x), next(nullptr) {} +}; + +ListNode* reverseList(ListNode* head) { + ListNode* prev = nullptr; + ListNode* curr = head; + + while (curr != nullptr) { + ListNode* next = curr->next; + curr->next = prev; + prev = curr; + curr = next; + } + return prev; +} \ No newline at end of file diff --git a/patterns/go/reverse_list.go b/patterns/go/reverse_list.go new file mode 100644 index 0000000..8cbcaed --- /dev/null +++ b/patterns/go/reverse_list.go @@ -0,0 +1,19 @@ +package main + +type ListNode struct { + Val int + Next *ListNode +} + +func reverseList(head *ListNode) *ListNode { + var prev *ListNode = nil + curr := head + + for curr != nil { + next := curr.Next + curr.Next = prev + prev = curr + curr = next + } + return prev +} diff --git a/patterns/java/ReverseLinkedList.java b/patterns/java/ReverseLinkedList.java new file mode 100644 index 0000000..3bd0843 --- /dev/null +++ b/patterns/java/ReverseLinkedList.java @@ -0,0 +1,20 @@ +package patterns.java; + +class ListNode { + int val; + ListNode next; +} + +public class ReverseLinkedList { + public ListNode reverseList(ListNode head) { + ListNode prev = null; // Previous node, initially null + ListNode curr = head; // Current node starts from the head + while (curr != null) { + ListNode next = curr.next; // Store next node + curr.next = prev; // Reverse the current node's pointer + prev = curr; // Move prev to current + curr = next; // Move curr to next + } + return prev; // New head of the reversed list + } +} diff --git a/patterns/javascript/reverseList.js b/patterns/javascript/reverseList.js new file mode 100644 index 0000000..317f50e --- /dev/null +++ b/patterns/javascript/reverseList.js @@ -0,0 +1,19 @@ +class ListNode { + constructor(val = 0, next = null) { + this.val = val; + this.next = next; + } +} + +function reverseList(head) { + let prev = null; + let curr = head; + + while (curr !== null) { + let next = curr.next; + curr.next = prev; + prev = curr; + curr = next; + } + return prev; +} \ No newline at end of file diff --git a/patterns/python/reverse_list.py b/patterns/python/reverse_list.py new file mode 100644 index 0000000..ec842b3 --- /dev/null +++ b/patterns/python/reverse_list.py @@ -0,0 +1,16 @@ +class ListNode: + def __init__(self, val=0, next=None): + self.val = val + self.next = next + +def reverse_list(head): + prev = None + curr = head + + while curr: + next_node = curr.next + curr.next = prev + prev = curr + curr = next_node + + return prev \ No newline at end of file diff --git a/patterns/typescript/reverseList.ts b/patterns/typescript/reverseList.ts new file mode 100644 index 0000000..d757f7e --- /dev/null +++ b/patterns/typescript/reverseList.ts @@ -0,0 +1,22 @@ +class ListNode { + val: number; + next: ListNode | null; + + constructor(val: number = 0, next: ListNode | null = null) { + this.val = val; + this.next = next; + } +} + +function reverseList(head: ListNode | null): ListNode | null { + let prev: ListNode | null = null; + let curr: ListNode | null = head; + + while (curr !== null) { + let next: ListNode | null = curr.next; + curr.next = prev; + prev = curr; + curr = next; + } + return prev; +} \ No newline at end of file From 3f41a4a5580627a16797583d1ea3e7bc05689a3a Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Tue, 31 Dec 2024 11:43:42 +0530 Subject: [PATCH 15/25] Update linked list in-place reversal pattern link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 408522f..23ffd54 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ If you want to practice curated list of LeetCode problems organized by patterns, - [Fast and Slow Pointers Pattern](https://www.youtube.com/watch?v=b139yf7Ik-E) - [Kadane's Algorithm](https://www.youtube.com/watch?v=NUWAXbSlsws) - [Two Pointers Pattern](https://blog.algomaster.io/p/69025a2e-b0d5-4705-8507-bba16c2691f1) -- [Linked List In-place Reversal Pattern](https://blog.algomaster.io/p/7dcce8e9-beee-4fef-8874-7aae025031b1) +- [Linked List In-place Reversal Pattern](https://www.youtube.com/watch?v=auoTGovuo9A) - [Sliding Window Pattern](https://blog.algomaster.io/p/f4412a17-7a3a-4d0b-8e39-9ea8f429bf7c) - [Monotonic Stack Pattern](https://blog.algomaster.io/p/5dabff21-11f4-470d-8e38-76ff07c63fdf) - [Overlapping Intervals Pattern](https://blog.algomaster.io/p/812e72f7-eced-4256-a4c1-00606ae50679) From 554f53e4cc2d59a8f508964a77e679b3cc9ed36e Mon Sep 17 00:00:00 2001 From: Arnab Das <93949960+Arnab7456@users.noreply.github.com> Date: Thu, 16 Jan 2025 13:55:17 +0530 Subject: [PATCH 16/25] Integer Overflow in Max Heap Comparator for K Closest Points to Origin The current implementation can potentially cause overflow when the distances are large. issue solve Id: #21 --- patterns/java/TopKElements.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/patterns/java/TopKElements.java b/patterns/java/TopKElements.java index c84c391..15946b1 100644 --- a/patterns/java/TopKElements.java +++ b/patterns/java/TopKElements.java @@ -126,7 +126,9 @@ private int getDistance(int[] point) { public int[][] kClosestPointsToOriginMaxHeapApproach(int[][] points, int k) { // Max heap with custom comparator to compare by distance - PriorityQueue maxHeap = new PriorityQueue<>((a, b) -> getDistance(b) - getDistance(a)); + PriorityQueue maxHeap = new PriorityQueue<>( + (a, b) -> Integer.compare(getDistance(b), getDistance(a)) + ); // Iterate through all points for (int[] point : points) { @@ -146,4 +148,4 @@ public int[][] kClosestPointsToOriginMaxHeapApproach(int[][] points, int k) { return result; } -} \ No newline at end of file +} From 4dbefcd302ef54861a0c3ac096a5fb5fb981d6be Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Wed, 22 Jan 2025 22:59:49 +0530 Subject: [PATCH 17/25] add start leetcode article --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 23ffd54..44ffba8 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ This repository contains awesome LeetCode resources to learn Data Structures and If you want to practice curated list of LeetCode problems organized by patterns, checkout [AlgoMaster.io](https://algomaster.io) ## 💡 Tips -- [How to Start LeetCode](https://www.youtube.com/watch?v=Nx4bvwU0DqE) +- [How to Start LeetCode](https://blog.algomaster.io/p/how-to-start-leetcode-in-2025) - [How I Mastered DSA](https://blog.algomaster.io/p/how-i-mastered-data-structures-and-algorithms) ## 📌 Fundamental Concepts From 9ba0ae38a7cb9293fc5c4bd66c06b00ef5680131 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Fri, 24 Jan 2025 19:09:55 +0530 Subject: [PATCH 18/25] add monotonic stack pattern --- patterns/c#/MonotonicStack.cs | 35 ++++++++++++++++++++ patterns/c++/KadaneAlgorithm.cpp | 19 +++++++++++ patterns/c++/MonotonicStack.cpp | 39 +++++++++++++++++++++++ patterns/go/monotonic_stack.go | 46 +++++++++++++++++++++++++++ patterns/java/MonotonicStack.java | 43 +++++++++++++++++++++++++ patterns/javascript/monotonicStack.js | 31 ++++++++++++++++++ patterns/python/monotonic_stack.py | 26 +++++++++++++++ patterns/typescript/monotonicStack.ts | 31 ++++++++++++++++++ 8 files changed, 270 insertions(+) create mode 100644 patterns/c#/MonotonicStack.cs create mode 100644 patterns/c++/MonotonicStack.cpp create mode 100644 patterns/go/monotonic_stack.go create mode 100644 patterns/java/MonotonicStack.java create mode 100644 patterns/javascript/monotonicStack.js create mode 100644 patterns/python/monotonic_stack.py create mode 100644 patterns/typescript/monotonicStack.ts diff --git a/patterns/c#/MonotonicStack.cs b/patterns/c#/MonotonicStack.cs new file mode 100644 index 0000000..2d1d89e --- /dev/null +++ b/patterns/c#/MonotonicStack.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; + +public class MonotonicStack { + public int[] NextGreaterElement(int[] nums) { + int n = nums.Length; + int[] result = new int[n]; + Array.Fill(result, -1); // Default to -1 if no greater element exists + Stack stack = new Stack(); // Stack stores indices + + for (int i = 0; i < n; i++) { + while (stack.Count > 0 && nums[i] > nums[stack.Peek()]) { + int index = stack.Pop(); + result[index] = nums[i]; + } + stack.Push(i); + } + return result; + } + + public int[] DailyTemperatures(int[] temperatures) { + int n = temperatures.Length; + int[] result = new int[n]; // Result array initialized with 0s + Stack stack = new Stack(); // Monotonic decreasing stack + + for (int i = 0; i < n; i++) { + while (stack.Count > 0 && temperatures[i] > temperatures[stack.Peek()]) { + int prevIndex = stack.Pop(); + result[prevIndex] = i - prevIndex; + } + stack.Push(i); + } + return result; + } +} \ No newline at end of file diff --git a/patterns/c++/KadaneAlgorithm.cpp b/patterns/c++/KadaneAlgorithm.cpp index e69de29..609f6ed 100644 --- a/patterns/c++/KadaneAlgorithm.cpp +++ b/patterns/c++/KadaneAlgorithm.cpp @@ -0,0 +1,19 @@ +#include +#include // For std::max + +class KadaneAlgorithm { +public: + int maxSubArray(std::vector& nums) { + int currentSum = nums[0]; // Start with the first element + int maxSum = nums[0]; // Initialize maxSum with the first element + + // Traverse the array from the second element + for (size_t i = 1; i < nums.size(); i++) { + // If currentSum is negative, reset to current element + currentSum = std::max(nums[i], currentSum + nums[i]); + // Update maxSum if currentSum is greater + maxSum = std::max(maxSum, currentSum); + } + return maxSum; + } +}; \ No newline at end of file diff --git a/patterns/c++/MonotonicStack.cpp b/patterns/c++/MonotonicStack.cpp new file mode 100644 index 0000000..e7ae2c8 --- /dev/null +++ b/patterns/c++/MonotonicStack.cpp @@ -0,0 +1,39 @@ +#include +#include + +using namespace std; + +class MonotonicStack { +public: + vector nextGreaterElement(vector& nums) { + int n = nums.size(); + vector result(n, -1); // Default to -1 if no greater element exists + stack stack; // Stack stores indices + + for (int i = 0; i < n; i++) { + while (!stack.empty() && nums[i] > nums[stack.top()]) { + int index = stack.top(); + stack.pop(); + result[index] = nums[i]; + } + stack.push(i); + } + return result; + } + + vector dailyTemperatures(vector& temperatures) { + int n = temperatures.size(); + vector result(n, 0); + stack stack; // Monotonic decreasing stack + + for (int i = 0; i < n; i++) { + while (!stack.empty() && temperatures[i] > temperatures[stack.top()]) { + int prevIndex = stack.top(); + stack.pop(); + result[prevIndex] = i - prevIndex; + } + stack.push(i); + } + return result; + } +}; \ No newline at end of file diff --git a/patterns/go/monotonic_stack.go b/patterns/go/monotonic_stack.go new file mode 100644 index 0000000..1f66f4b --- /dev/null +++ b/patterns/go/monotonic_stack.go @@ -0,0 +1,46 @@ +package main + +import "fmt" + +func nextGreaterElement(nums []int) []int { + n := len(nums) + result := make([]int, n) + for i := range result { + result[i] = -1 // Default to -1 if no greater element exists + } + stack := []int{} // Stack stores indices + + for i := 0; i < n; i++ { + for len(stack) > 0 && nums[i] > nums[stack[len(stack)-1]] { + index := stack[len(stack)-1] + stack = stack[:len(stack)-1] + result[index] = nums[i] + } + stack = append(stack, i) + } + return result +} + +func dailyTemperatures(temperatures []int) []int { + n := len(temperatures) + result := make([]int, n) // Result array initialized with 0s + stack := []int{} // Monotonic decreasing stack + + for i := 0; i < n; i++ { + for len(stack) > 0 && temperatures[i] > temperatures[stack[len(stack)-1]] { + prevIndex := stack[len(stack)-1] + stack = stack[:len(stack)-1] + result[prevIndex] = i - prevIndex + } + stack = append(stack, i) + } + return result +} + +func main() { + nums := []int{2, 1, 5, 6, 2, 3} + fmt.Println(nextGreaterElement(nums)) + + temperatures := []int{73, 74, 75, 71, 69, 72, 76, 73} + fmt.Println(dailyTemperatures(temperatures)) +} diff --git a/patterns/java/MonotonicStack.java b/patterns/java/MonotonicStack.java new file mode 100644 index 0000000..920b61f --- /dev/null +++ b/patterns/java/MonotonicStack.java @@ -0,0 +1,43 @@ +package patterns.java; + +import java.util.Arrays; +import java.util.Stack; + +public class MonotonicStack { + + public int[] nextGreaterElement(int[] nums) { + int n = nums.length; + int[] result = new int[n]; // Output array + Arrays.fill(result, -1); // Default to -1 if no greater element exists + Stack stack = new Stack<>(); // Stack stores indices + + // Iterate through the array + for (int i = 0; i < n; i++) { + // While stack is not empty and current element is greater than stack top + while (!stack.isEmpty() && nums[i] > nums[stack.peek()]) { + int index = stack.pop(); // Pop the top element + result[index] = nums[i]; // The current element is the Next Greater Element + } + stack.push(i); // Push the current index onto the stack + } + return result; + } + + public int[] dailyTemperatures(int[] temperatures) { + int n = temperatures.length; + int[] result = new int[n]; // Result array initialized with 0s + Stack stack = new Stack<>(); // Monotonic decreasing stack (stores indices) + + // Iterate through the temperature array + for (int i = 0; i < n; i++) { + // While stack is not empty AND the current temperature is warmer than the temperature at stack top + while (!stack.isEmpty() && temperatures[i] > temperatures[stack.peek()]) { + int prevIndex = stack.pop(); // Pop the previous day's index + result[prevIndex] = i - prevIndex; // Calculate the wait time + } + stack.push(i); // Push current index onto the stack + } + + return result; // Return the computed results + } +} \ No newline at end of file diff --git a/patterns/javascript/monotonicStack.js b/patterns/javascript/monotonicStack.js new file mode 100644 index 0000000..94918c4 --- /dev/null +++ b/patterns/javascript/monotonicStack.js @@ -0,0 +1,31 @@ +class MonotonicStack { + nextGreaterElement(nums) { + let n = nums.length; + let result = new Array(n).fill(-1); // Default to -1 if no greater element exists + let stack = []; // Stack stores indices + + for (let i = 0; i < n; i++) { + while (stack.length > 0 && nums[i] > nums[stack[stack.length - 1]]) { + let index = stack.pop(); + result[index] = nums[i]; + } + stack.push(i); + } + return result; + } + + dailyTemperatures(temperatures) { + let n = temperatures.length; + let result = new Array(n).fill(0); // Result array initialized with 0s + let stack = []; // Monotonic decreasing stack + + for (let i = 0; i < n; i++) { + while (stack.length > 0 && temperatures[i] > temperatures[stack[stack.length - 1]]) { + let prevIndex = stack.pop(); + result[prevIndex] = i - prevIndex; + } + stack.push(i); + } + return result; + } +} \ No newline at end of file diff --git a/patterns/python/monotonic_stack.py b/patterns/python/monotonic_stack.py new file mode 100644 index 0000000..62e51ce --- /dev/null +++ b/patterns/python/monotonic_stack.py @@ -0,0 +1,26 @@ +class MonotonicStack: + def next_greater_element(self, nums): + n = len(nums) + result = [-1] * n # Default to -1 if no greater element exists + stack = [] # Stack stores indices + + for i in range(n): + while stack and nums[i] > nums[stack[-1]]: + index = stack.pop() + result[index] = nums[i] + stack.append(i) + + return result + + def daily_temperatures(self, temperatures): + n = len(temperatures) + result = [0] * n # Result array initialized with 0s + stack = [] # Monotonic decreasing stack + + for i in range(n): + while stack and temperatures[i] > temperatures[stack[-1]]: + prev_index = stack.pop() + result[prev_index] = i - prev_index + stack.append(i) + + return result \ No newline at end of file diff --git a/patterns/typescript/monotonicStack.ts b/patterns/typescript/monotonicStack.ts new file mode 100644 index 0000000..a878002 --- /dev/null +++ b/patterns/typescript/monotonicStack.ts @@ -0,0 +1,31 @@ +class MonotonicStack { + nextGreaterElement(nums: number[]): number[] { + let n = nums.length; + let result: number[] = new Array(n).fill(-1); // Default to -1 if no greater element exists + let stack: number[] = []; // Stack stores indices + + for (let i = 0; i < n; i++) { + while (stack.length > 0 && nums[i] > nums[stack[stack.length - 1]]) { + let index = stack.pop()!; + result[index] = nums[i]; + } + stack.push(i); + } + return result; + } + + dailyTemperatures(temperatures: number[]): number[] { + let n = temperatures.length; + let result: number[] = new Array(n).fill(0); // Result array initialized with 0s + let stack: number[] = []; // Monotonic decreasing stack + + for (let i = 0; i < n; i++) { + while (stack.length > 0 && temperatures[i] > temperatures[stack[stack.length - 1]]) { + let prevIndex = stack.pop()!; + result[prevIndex] = i - prevIndex; + } + stack.push(i); + } + return result; + } +} \ No newline at end of file From 021e97d1daee2b52120143ec07efda48cad4c44f Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Fri, 24 Jan 2025 20:59:29 +0530 Subject: [PATCH 19/25] Add monotonic stack video --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 44ffba8..25590db 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ If you want to practice curated list of LeetCode problems organized by patterns, - [Two Pointers Pattern](https://blog.algomaster.io/p/69025a2e-b0d5-4705-8507-bba16c2691f1) - [Linked List In-place Reversal Pattern](https://www.youtube.com/watch?v=auoTGovuo9A) - [Sliding Window Pattern](https://blog.algomaster.io/p/f4412a17-7a3a-4d0b-8e39-9ea8f429bf7c) -- [Monotonic Stack Pattern](https://blog.algomaster.io/p/5dabff21-11f4-470d-8e38-76ff07c63fdf) +- [Monotonic Stack Pattern](https://www.youtube.com/watch?v=DtJVwbbicjQ) - [Overlapping Intervals Pattern](https://blog.algomaster.io/p/812e72f7-eced-4256-a4c1-00606ae50679) - [Backtracking Pattern](https://blog.algomaster.io/p/81d42ca2-600c-4252-aa33-a56462090048) - [Modified Binary Search Pattern](https://blog.algomaster.io/p/d0d81b04-4c2a-4b45-a101-5137c3146686) From 3bb0171f4a9499a7398bac9e87b882d9b8ae0c05 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Sat, 25 Jan 2025 18:29:22 +0530 Subject: [PATCH 20/25] add sliding window pattern --- patterns/c#/SlidingWindow.cs | 69 +++++++++++++++++++++ patterns/c++/SlidingWindow.cpp | 74 +++++++++++++++++++++++ patterns/go/sliding_window.go | 81 +++++++++++++++++++++++++ patterns/java/SlidingWindow.java | 90 ++++++++++++++++++++++++++++ patterns/javascript/slidingWindow.js | 62 +++++++++++++++++++ patterns/python/sliding_window.py | 46 ++++++++++++++ patterns/typescript/slidingWindow.ts | 62 +++++++++++++++++++ 7 files changed, 484 insertions(+) create mode 100644 patterns/c#/SlidingWindow.cs create mode 100644 patterns/c++/SlidingWindow.cpp create mode 100644 patterns/go/sliding_window.go create mode 100644 patterns/java/SlidingWindow.java create mode 100644 patterns/javascript/slidingWindow.js create mode 100644 patterns/python/sliding_window.py create mode 100644 patterns/typescript/slidingWindow.ts diff --git a/patterns/c#/SlidingWindow.cs b/patterns/c#/SlidingWindow.cs new file mode 100644 index 0000000..78fe833 --- /dev/null +++ b/patterns/c#/SlidingWindow.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; + +public class SlidingWindow { + public double FindMaxAverageBruteForce(int[] nums, int k) { + int n = nums.Length; + double maxAvg = double.MinValue; + + for (int i = 0; i <= n - k; i++) { + int sum = 0; + for (int j = i; j < i + k; j++) { + sum += nums[j]; + } + maxAvg = Math.Max(maxAvg, (double)sum / k); + } + return maxAvg; + } + + public double FindMaxAverageSlidingWindow(int[] nums, int k) { + int n = nums.Length; + int sum = 0; + + for (int i = 0; i < k; i++) { + sum += nums[i]; + } + + int maxSum = sum; + + for (int i = k; i < n; i++) { + sum += nums[i]; + sum -= nums[i - k]; + maxSum = Math.Max(maxSum, sum); + } + + return (double)maxSum / k; + } + + public int LengthOfLongestSubstringSlidingWindow(string s) { + HashSet seen = new HashSet(); + int maxLength = 0, left = 0; + + for (int right = 0; right < s.Length; right++) { + while (seen.Contains(s[right])) { + seen.Remove(s[left]); + left++; + } + seen.Add(s[right]); + maxLength = Math.Max(maxLength, right - left + 1); + } + return maxLength; + } + + public int LengthOfLongestSubstringSlidingWindowFrequencyArray(string s) { + int[] freq = new int[128]; + int maxLength = 0, left = 0; + + for (int right = 0; right < s.Length; right++) { + freq[s[right]]++; + + while (freq[s[right]] > 1) { + freq[s[left]]--; + left++; + } + + maxLength = Math.Max(maxLength, right - left + 1); + } + return maxLength; + } +} \ No newline at end of file diff --git a/patterns/c++/SlidingWindow.cpp b/patterns/c++/SlidingWindow.cpp new file mode 100644 index 0000000..6d12d0c --- /dev/null +++ b/patterns/c++/SlidingWindow.cpp @@ -0,0 +1,74 @@ +#include +#include +#include +#include + +using namespace std; + +class SlidingWindow { +public: + double findMaxAverageBruteForce(vector& nums, int k) { + int n = nums.size(); + double maxAvg = INT_MIN; + + for (int i = 0; i <= n - k; i++) { + int sum = 0; + for (int j = i; j < i + k; j++) { + sum += nums[j]; + } + maxAvg = max(maxAvg, (double)sum / k); + } + return maxAvg; + } + + double findMaxAverageSlidingWindow(vector& nums, int k) { + int n = nums.size(); + int sum = 0; + + for (int i = 0; i < k; i++) { + sum += nums[i]; + } + + int maxSum = sum; + + for (int i = k; i < n; i++) { + sum += nums[i]; + sum -= nums[i - k]; + maxSum = max(maxSum, sum); + } + + return (double)maxSum / k; + } + + int lengthOfLongestSubstringSlidingWindow(string s) { + unordered_set seen; + int maxLength = 0, left = 0; + + for (int right = 0; right < s.size(); right++) { + while (seen.count(s[right])) { + seen.erase(s[left]); + left++; + } + seen.insert(s[right]); + maxLength = max(maxLength, right - left + 1); + } + return maxLength; + } + + int lengthOfLongestSubstringSlidingWindowFrequencyArray(string s) { + vector freq(128, 0); + int maxLength = 0, left = 0; + + for (int right = 0; right < s.size(); right++) { + freq[s[right]]++; + + while (freq[s[right]] > 1) { + freq[s[left]]--; + left++; + } + + maxLength = max(maxLength, right - left + 1); + } + return maxLength; + } +}; \ No newline at end of file diff --git a/patterns/go/sliding_window.go b/patterns/go/sliding_window.go new file mode 100644 index 0000000..056b87d --- /dev/null +++ b/patterns/go/sliding_window.go @@ -0,0 +1,81 @@ +package main + +import ( + "math" +) + +// Brute Force Approach - O(n * k) +func findMaxAverageBruteForce(nums []int, k int) float64 { + n := len(nums) + maxAvg := math.Inf(-1) + + for i := 0; i <= n-k; i++ { + sum := 0 + for j := i; j < i+k; j++ { + sum += nums[j] + } + maxAvg = math.Max(maxAvg, float64(sum)/float64(k)) + } + return maxAvg +} + +// Sliding Window Approach - O(n) +func findMaxAverageSlidingWindow(nums []int, k int) float64 { + sum := 0 + for i := 0; i < k; i++ { + sum += nums[i] + } + + maxSum := sum + + for i := k; i < len(nums); i++ { + sum += nums[i] - nums[i-k] + if sum > maxSum { + maxSum = sum + } + } + + return float64(maxSum) / float64(k) +} + +// Sliding Window for Longest Substring Without Repeating Characters +func lengthOfLongestSubstringSlidingWindow(s string) int { + seen := make(map[byte]bool) + maxLength, left := 0, 0 + + for right := 0; right < len(s); right++ { + for seen[s[right]] { + delete(seen, s[left]) + left++ + } + seen[s[right]] = true + maxLength = max(maxLength, right-left+1) + } + return maxLength +} + +// Sliding Window using Frequency Array +func lengthOfLongestSubstringSlidingWindowFrequencyArray(s string) int { + freq := make([]int, 128) + maxLength, left := 0, 0 + + for right := 0; right < len(s); right++ { + freq[s[right]]++ + + for freq[s[right]] > 1 { + freq[s[left]]-- + left++ + } + + maxLength = max(maxLength, right-left+1) + } + return maxLength +} + +// Helper function to get max of two numbers +func max(a, b int) int { + if a > b { + return a + } + return b +} diff --git a/patterns/java/SlidingWindow.java b/patterns/java/SlidingWindow.java new file mode 100644 index 0000000..7fe3d79 --- /dev/null +++ b/patterns/java/SlidingWindow.java @@ -0,0 +1,90 @@ +package patterns.java; + +import java.util.HashSet; + +public class SlidingWindow { + public double findMaxAverageBruteForce(int[] nums, int k) { + int n = nums.length; + double maxAvg = Integer.MIN_VALUE; + + // Iterate through all possible subarrays of length k + for (int i = 0; i <= n - k; i++) { + int sum = 0; + + // Calculate sum of subarray starting at index i + for (int j = i; j < i + k; j++) { + sum += nums[j]; + } + + // Compute average and update maxAvg + maxAvg = Math.max(maxAvg, (double) sum / k); + } + return maxAvg; + } + + public double findMaxAverageSlidingWindow(int[] nums, int k) { + int n = nums.length; + + // Compute the sum of the first 'k' elements + int sum = 0; + for (int i = 0; i < k; i++) { + sum += nums[i]; + } + + // Initialize maxSum as the sum of the first window + int maxSum = sum; + + // Slide the window across the array + for (int i = k; i < n; i++) { + sum += nums[i]; // Add new element entering window + sum -= nums[i - k]; // Remove element leaving window + maxSum = Math.max(maxSum, sum); // Update maxSum + } + + // Return maximum average + return (double) maxSum / k; + } + + public int lengthOfLongestSubstringSlidingWindow(String s) { + int n = s.length(); + HashSet seen = new HashSet<>(); // Store characters in the current window + int maxLength = 0; + int left = 0; + + // Expand window by moving 'right' + for (int right = 0; right < n; right++) { + // If a duplicate is found, shrink the window from the left + while (seen.contains(s.charAt(right))) { + seen.remove(s.charAt(left)); + left++; + } + // Add current character to window and update max length + seen.add(s.charAt(right)); + maxLength = Math.max(maxLength, right - left + 1); + } + return maxLength; + } + + public int lengthOfLongestSubstringSlidingWindowFrequencyArray(String s) { + int n = s.length(); + int[] freq = new int[128]; // ASCII character frequency array + int maxLength = 0; + int left = 0; + + // Expand window by moving 'right' + for (int right = 0; right < n; right++) { + char currentChar = s.charAt(right); + freq[currentChar]++; // Increase frequency of the current character + + // If there is a duplicate, shrink the window from the left + while (freq[currentChar] > 1) { + freq[s.charAt(left)]--; // Remove character at left pointer + left++; // Shrink window + } + + // Update maximum window size + maxLength = Math.max(maxLength, right - left + 1); + } + return maxLength; + } +} \ No newline at end of file diff --git a/patterns/javascript/slidingWindow.js b/patterns/javascript/slidingWindow.js new file mode 100644 index 0000000..2e80ef0 --- /dev/null +++ b/patterns/javascript/slidingWindow.js @@ -0,0 +1,62 @@ +class SlidingWindow { + // Brute Force Approach - O(n * k) + findMaxAverageBruteForce(nums, k) { + let maxAvg = -Infinity; + + for (let i = 0; i <= nums.length - k; i++) { + let sum = 0; + for (let j = i; j < i + k; j++) { + sum += nums[j]; + } + maxAvg = Math.max(maxAvg, sum / k); + } + return maxAvg; + } + + // Sliding Window Approach - O(n) + findMaxAverageSlidingWindow(nums, k) { + let sum = nums.slice(0, k).reduce((a, b) => a + b, 0); + let maxSum = sum; + + for (let i = k; i < nums.length; i++) { + sum += nums[i] - nums[i - k]; + maxSum = Math.max(maxSum, sum); + } + + return maxSum / k; + } + + // Sliding Window for Longest Substring Without Repeating Characters + lengthOfLongestSubstringSlidingWindow(s) { + let seen = new Set(); + let maxLength = 0, left = 0; + + for (let right = 0; right < s.length; right++) { + while (seen.has(s[right])) { + seen.delete(s[left]); + left++; + } + seen.add(s[right]); + maxLength = Math.max(maxLength, right - left + 1); + } + return maxLength; + } + + // Sliding Window using Frequency Array + lengthOfLongestSubstringSlidingWindowFrequencyArray(s) { + let freq = new Array(128).fill(0); + let maxLength = 0, left = 0; + + for (let right = 0; right < s.length; right++) { + freq[s.charCodeAt(right)]++; + + while (freq[s.charCodeAt(right)] > 1) { + freq[s.charCodeAt(left)]--; + left++; + } + + maxLength = Math.max(maxLength, right - left + 1); + } + return maxLength; + } +} \ No newline at end of file diff --git a/patterns/python/sliding_window.py b/patterns/python/sliding_window.py new file mode 100644 index 0000000..b42e33d --- /dev/null +++ b/patterns/python/sliding_window.py @@ -0,0 +1,46 @@ +class SlidingWindow: + def find_max_average_brute_force(self, nums, k): + max_avg = float('-inf') + + for i in range(len(nums) - k + 1): + max_avg = max(max_avg, sum(nums[i:i + k]) / k) + + return max_avg + + def find_max_average_sliding_window(self, nums, k): + sum_window = sum(nums[:k]) + max_sum = sum_window + + for i in range(k, len(nums)): + sum_window += nums[i] - nums[i - k] + max_sum = max(max_sum, sum_window) + + return max_sum / k + + def length_of_longest_substring_sliding_window(self, s): + seen = set() + max_length = left = 0 + + for right in range(len(s)): + while s[right] in seen: + seen.remove(s[left]) + left += 1 + seen.add(s[right]) + max_length = max(max_length, right - left + 1) + + return max_length + + def length_of_longest_substring_sliding_window_frequency_array(self, s): + freq = [0] * 128 + max_length = left = 0 + + for right in range(len(s)): + freq[ord(s[right])] += 1 + + while freq[ord(s[right])] > 1: + freq[ord(s[left])] -= 1 + left += 1 + + max_length = max(max_length, right - left + 1) + + return max_length \ No newline at end of file diff --git a/patterns/typescript/slidingWindow.ts b/patterns/typescript/slidingWindow.ts new file mode 100644 index 0000000..86a2c8d --- /dev/null +++ b/patterns/typescript/slidingWindow.ts @@ -0,0 +1,62 @@ +class SlidingWindow { + // Brute Force Approach - O(n * k) + findMaxAverageBruteForce(nums: number[], k: number): number { + let maxAvg = -Infinity; + + for (let i = 0; i <= nums.length - k; i++) { + let sum = 0; + for (let j = i; j < i + k; j++) { + sum += nums[j]; + } + maxAvg = Math.max(maxAvg, sum / k); + } + return maxAvg; + } + + // Sliding Window Approach - O(n) + findMaxAverageSlidingWindow(nums: number[], k: number): number { + let sum = nums.slice(0, k).reduce((a, b) => a + b, 0); + let maxSum = sum; + + for (let i = k; i < nums.length; i++) { + sum += nums[i] - nums[i - k]; + maxSum = Math.max(maxSum, sum); + } + + return maxSum / k; + } + + // Sliding Window for Longest Substring Without Repeating Characters + lengthOfLongestSubstringSlidingWindow(s: string): number { + let seen = new Set(); + let maxLength = 0, left = 0; + + for (let right = 0; right < s.length; right++) { + while (seen.has(s[right])) { + seen.delete(s[left]); + left++; + } + seen.add(s[right]); + maxLength = Math.max(maxLength, right - left + 1); + } + return maxLength; + } + + // Sliding Window using Frequency Array + lengthOfLongestSubstringSlidingWindowFrequencyArray(s: string): number { + let freq = new Array(128).fill(0); + let maxLength = 0, left = 0; + + for (let right = 0; right < s.length; right++) { + freq[s.charCodeAt(right)]++; + + while (freq[s.charCodeAt(right)] > 1) { + freq[s.charCodeAt(left)]--; + left++; + } + + maxLength = Math.max(maxLength, right - left + 1); + } + return maxLength; + } +} \ No newline at end of file From 3f52ae5f01371a049e59531341acb6b721f6c3b1 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Sat, 25 Jan 2025 23:16:42 +0530 Subject: [PATCH 21/25] Update Sliding Window url --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 25590db..c38d716 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ If you want to practice curated list of LeetCode problems organized by patterns, - [Top 'K' Elements Pattern](https://www.youtube.com/watch?v=6_v6OoxvMOE) - [Fast and Slow Pointers Pattern](https://www.youtube.com/watch?v=b139yf7Ik-E) - [Kadane's Algorithm](https://www.youtube.com/watch?v=NUWAXbSlsws) +- [Sliding Window Pattern](https://www.youtube.com/watch?v=y2d0VHdvfdc) - [Two Pointers Pattern](https://blog.algomaster.io/p/69025a2e-b0d5-4705-8507-bba16c2691f1) - [Linked List In-place Reversal Pattern](https://www.youtube.com/watch?v=auoTGovuo9A) - [Sliding Window Pattern](https://blog.algomaster.io/p/f4412a17-7a3a-4d0b-8e39-9ea8f429bf7c) From aa1fbcc9d84aa1d772bbcbc19fc5ceeb10bb02a9 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Sun, 26 Jan 2025 19:22:53 +0530 Subject: [PATCH 22/25] add two pointers pattern --- patterns/c#/TwoPointers.cs | 59 +++++++++++++++++++++++++ patterns/c++/TwoPointers.cpp | 64 +++++++++++++++++++++++++++ patterns/go/two_pointers.go | 69 ++++++++++++++++++++++++++++++ patterns/java/TwoPointers.java | 59 +++++++++++++++++++++++++ patterns/javascript/twoPointers.js | 68 +++++++++++++++++++++++++++++ patterns/python/two_pointers.py | 48 +++++++++++++++++++++ patterns/typescript/twoPointers.ts | 57 ++++++++++++++++++++++++ 7 files changed, 424 insertions(+) create mode 100644 patterns/c#/TwoPointers.cs create mode 100644 patterns/c++/TwoPointers.cpp create mode 100644 patterns/go/two_pointers.go create mode 100644 patterns/java/TwoPointers.java create mode 100644 patterns/javascript/twoPointers.js create mode 100644 patterns/python/two_pointers.py create mode 100644 patterns/typescript/twoPointers.ts diff --git a/patterns/c#/TwoPointers.cs b/patterns/c#/TwoPointers.cs new file mode 100644 index 0000000..086b691 --- /dev/null +++ b/patterns/c#/TwoPointers.cs @@ -0,0 +1,59 @@ +using System; + +public class TwoPointers { + // Move Zeroes using Two Pointers + public void MoveZeroesTwoPointers(int[] nums) { + int left = 0; // Pointer for placing non-zero elements + + // Iterate with right pointer + for (int right = 0; right < nums.Length; right++) { + if (nums[right] != 0) { + // Swap elements if right pointer finds a non-zero + (nums[left], nums[right]) = (nums[right], nums[left]); + left++; // Move left pointer forward + } + } + } + + // Brute Force approach for Container with Most Water + public int MaxAreaBruteForce(int[] height) { + int n = height.Length; + int maxArea = 0; + + // Check all pairs (i, j) + for (int i = 0; i < n; i++) { + for (int j = i + 1; j < n; j++) { + // Compute the minimum height and width + int minHeight = Math.Min(height[i], height[j]); + int width = j - i; + int area = minHeight * width; // Compute water contained + + maxArea = Math.Max(maxArea, area); // Update max water + } + } + return maxArea; + } + + // Two Pointers approach for Container with Most Water + public int MaxAreaTwoPointers(int[] height) { + int left = 0, right = height.Length - 1; + int maxArea = 0; + + // Move pointers toward each other + while (left < right) { + int width = right - left; // Distance between lines + int minHeight = Math.Min(height[left], height[right]); // Compute height + int area = minHeight * width; // Compute water contained + + maxArea = Math.Max(maxArea, area); // Update max water + + // Move the pointer pointing to the shorter height + if (height[left] < height[right]) { + left++; // Move left pointer forward + } else { + right--; // Move right pointer backward + } + } + return maxArea; + } +} \ No newline at end of file diff --git a/patterns/c++/TwoPointers.cpp b/patterns/c++/TwoPointers.cpp new file mode 100644 index 0000000..8faea2b --- /dev/null +++ b/patterns/c++/TwoPointers.cpp @@ -0,0 +1,64 @@ +#include +#include +#include + +using namespace std; + +class TwoPointers { +public: + // Move Zeroes using Two Pointers + void moveZeroesTwoPointers(vector& nums) { + int left = 0; // Pointer for placing non-zero elements + + // Iterate with right pointer + for (int right = 0; right < nums.size(); right++) { + if (nums[right] != 0) { + // Swap elements if right pointer finds a non-zero + swap(nums[left], nums[right]); + left++; // Move left pointer forward + } + } + } + + // Brute Force approach for Container with Most Water + int maxAreaBruteForce(vector& height) { + int n = height.size(); + int maxArea = 0; + + // Check all pairs (i, j) + for (int i = 0; i < n; i++) { + for (int j = i + 1; j < n; j++) { + // Compute the minimum height and width + int minHeight = min(height[i], height[j]); + int width = j - i; + int area = minHeight * width; // Compute water contained + + maxArea = max(maxArea, area); // Update max water + } + } + return maxArea; + } + + // Two Pointers approach for Container with Most Water + int maxAreaTwoPointers(vector& height) { + int left = 0, right = height.size() - 1; + int maxArea = 0; + + // Move pointers toward each other + while (left < right) { + int width = right - left; // Distance between lines + int minHeight = min(height[left], height[right]); // Compute height + int area = minHeight * width; // Compute water contained + + maxArea = max(maxArea, area); // Update max water + + // Move the pointer pointing to the shorter height + if (height[left] < height[right]) { + left++; // Move left pointer forward + } else { + right--; // Move right pointer backward + } + } + return maxArea; + } +}; \ No newline at end of file diff --git a/patterns/go/two_pointers.go b/patterns/go/two_pointers.go new file mode 100644 index 0000000..1433c48 --- /dev/null +++ b/patterns/go/two_pointers.go @@ -0,0 +1,69 @@ +package main + +// Move Zeroes using Two Pointers +func moveZeroesTwoPointers(nums []int) { + left := 0 // Pointer for placing non-zero elements + + // Iterate with right pointer + for right := 0; right < len(nums); right++ { + if nums[right] != 0 { + // Swap elements if right pointer finds a non-zero + nums[left], nums[right] = nums[right], nums[left] + left++ // Move left pointer forward + } + } +} + +// Brute Force approach for Container with Most Water +func maxAreaBruteForce(height []int) int { + n := len(height) + maxArea := 0 + + // Check all pairs (i, j) + for i := 0; i < n; i++ { + for j := i + 1; j < n; j++ { + // Compute the minimum height and width + minHeight := min(height[i], height[j]) + width := j - i + area := minHeight * width // Compute water contained + + if area > maxArea { + maxArea = area // Update max water + } + } + } + return maxArea +} + +// Two Pointers approach for Container with Most Water +func maxAreaTwoPointers(height []int) int { + left, right := 0, len(height)-1 + maxArea := 0 + + // Move pointers toward each other + for left < right { + width := right - left // Distance between lines + minHeight := min(height[left], height[right]) // Compute height + area := minHeight * width // Compute water contained + + if area > maxArea { + maxArea = area // Update max water + } + + // Move the pointer pointing to the shorter height + if height[left] < height[right] { + left++ // Move left pointer forward + } else { + right-- // Move right pointer backward + } + } + return maxArea +} + +// Helper function to return the minimum of two integers +func min(a, b int) int { + if a < b { + return a + } + return b +} diff --git a/patterns/java/TwoPointers.java b/patterns/java/TwoPointers.java new file mode 100644 index 0000000..35cb395 --- /dev/null +++ b/patterns/java/TwoPointers.java @@ -0,0 +1,59 @@ +package patterns.java; + +public class TwoPointers { + + public void moveZeroesTwoPointers(int[] nums) { + int left = 0; // Pointer for placing non-zero elements + + // Iterate with right pointer + for (int right = 0; right < nums.length; right++) { + if (nums[right] != 0) { + // Swap elements if right pointer finds a non-zero + int temp = nums[left]; + nums[left] = nums[right]; + nums[right] = temp; + left++; // Move left pointer forward + } + } + } + + public int maxAreaBruteForce(int[] height) { + int n = height.length; + int maxArea = 0; + + // Check all pairs (i, j) + for (int i = 0; i < n; i++) { + for (int j = i + 1; j < n; j++) { + // Height of the container + int minHeight = Math.min(height[i], height[j]); + int width = j - i; // Distance between lines + int area = minHeight * width; // Compute water contained + + maxArea = Math.max(maxArea, area); // Update max water + } + } + return maxArea; + } + + public int maxAreaTwoPointers(int[] height) { + int left = 0, right = height.length - 1; + int maxArea = 0; + + // Move pointers toward each other + while (left <= right) { + int width = right - left; // Distance between lines + int minHeight = Math.min(height[left], height[right]); + int area = minHeight * width; // Compute water contained + + maxArea = Math.max(maxArea, area); // Update max water + + // Move the pointer pointing to the shorter height + if (height[left] < height[right]) { + left++; // Move left pointer forward + } else { + right--; // Move right pointer backward + } + } + return maxArea; + } +} \ No newline at end of file diff --git a/patterns/javascript/twoPointers.js b/patterns/javascript/twoPointers.js new file mode 100644 index 0000000..5c46a59 --- /dev/null +++ b/patterns/javascript/twoPointers.js @@ -0,0 +1,68 @@ +class TwoPointers { + /** + * Move Zeroes using Two Pointers + * @param {number[]} nums - Input array + */ + moveZeroesTwoPointers(nums) { + let left = 0; // Pointer for placing non-zero elements + + // Iterate with right pointer + for (let right = 0; right < nums.length; right++) { + if (nums[right] !== 0) { + // Swap elements if right pointer finds a non-zero + [nums[left], nums[right]] = [nums[right], nums[left]]; + left++; // Move left pointer forward + } + } + } + + /** + * Brute Force approach for Container with Most Water + * @param {number[]} height - Array of heights + * @return {number} - Maximum water that can be contained + */ + maxAreaBruteForce(height) { + let maxArea = 0; + let n = height.length; + + // Check all pairs (i, j) + for (let i = 0; i < n; i++) { + for (let j = i + 1; j < n; j++) { + // Compute the minimum height and width + let minHeight = Math.min(height[i], height[j]); + let width = j - i; + let area = minHeight * width; // Compute water contained + + maxArea = Math.max(maxArea, area); // Update max water + } + } + return maxArea; + } + + /** + * Two Pointers approach for Container with Most Water + * @param {number[]} height - Array of heights + * @return {number} - Maximum water that can be contained + */ + maxAreaTwoPointers(height) { + let left = 0, right = height.length - 1; + let maxArea = 0; + + // Move pointers toward each other + while (left < right) { + let width = right - left; // Distance between lines + let minHeight = Math.min(height[left], height[right]); // Compute height + let area = minHeight * width; // Compute water contained + + maxArea = Math.max(maxArea, area); // Update max water + + // Move the pointer pointing to the shorter height + if (height[left] < height[right]) { + left++; // Move left pointer forward + } else { + right--; // Move right pointer backward + } + } + return maxArea; + } +} \ No newline at end of file diff --git a/patterns/python/two_pointers.py b/patterns/python/two_pointers.py new file mode 100644 index 0000000..3e874f0 --- /dev/null +++ b/patterns/python/two_pointers.py @@ -0,0 +1,48 @@ +class TwoPointers: + # Move Zeroes using Two Pointers + def move_zeroes_two_pointers(self, nums): + left = 0 # Pointer for placing non-zero elements + + # Iterate with right pointer + for right in range(len(nums)): + if nums[right] != 0: + # Swap elements if right pointer finds a non-zero + nums[left], nums[right] = nums[right], nums[left] + left += 1 # Move left pointer forward + + # Brute Force approach for Container with Most Water + def max_area_brute_force(self, height): + n = len(height) + max_area = 0 + + # Check all pairs (i, j) + for i in range(n): + for j in range(i + 1, n): + # Compute the minimum height and width + min_height = min(height[i], height[j]) + width = j - i + area = min_height * width # Compute water contained + + max_area = max(max_area, area) # Update max water + return max_area + + # Two Pointers approach for Container with Most Water + def max_area_two_pointers(self, height): + left, right = 0, len(height) - 1 + max_area = 0 + + # Move pointers toward each other + while left < right: + width = right - left # Distance between lines + min_height = min(height[left], height[right]) # Compute height + area = min_height * width # Compute water contained + + max_area = max(max_area, area) # Update max water + + # Move the pointer pointing to the shorter height + if height[left] < height[right]: + left += 1 # Move left pointer forward + else: + right -= 1 # Move right pointer backward + + return max_area \ No newline at end of file diff --git a/patterns/typescript/twoPointers.ts b/patterns/typescript/twoPointers.ts new file mode 100644 index 0000000..8587625 --- /dev/null +++ b/patterns/typescript/twoPointers.ts @@ -0,0 +1,57 @@ +class TwoPointers { + // Move Zeroes using Two Pointers + moveZeroesTwoPointers(nums: number[]): void { + let left = 0; // Pointer for placing non-zero elements + + // Iterate with right pointer + for (let right = 0; right < nums.length; right++) { + if (nums[right] !== 0) { + // Swap elements if right pointer finds a non-zero + [nums[left], nums[right]] = [nums[right], nums[left]]; + left++; // Move left pointer forward + } + } + } + + // Brute Force approach for Container with Most Water + maxAreaBruteForce(height: number[]): number { + let maxArea = 0; + let n = height.length; + + // Check all pairs (i, j) + for (let i = 0; i < n; i++) { + for (let j = i + 1; j < n; j++) { + // Compute the minimum height and width + let minHeight = Math.min(height[i], height[j]); + let width = j - i; + let area = minHeight * width; // Compute water contained + + maxArea = Math.max(maxArea, area); // Update max water + } + } + return maxArea; + } + + // Two Pointers approach for Container with Most Water + maxAreaTwoPointers(height: number[]): number { + let left = 0, right = height.length - 1; + let maxArea = 0; + + // Move pointers toward each other + while (left < right) { + let width = right - left; // Distance between lines + let minHeight = Math.min(height[left], height[right]); // Compute height + let area = minHeight * width; // Compute water contained + + maxArea = Math.max(maxArea, area); // Update max water + + // Move the pointer pointing to the shorter height + if (height[left] < height[right]) { + left++; // Move left pointer forward + } else { + right--; // Move right pointer backward + } + } + return maxArea; + } +} \ No newline at end of file From c4a4f662ee6e41ae2be1c1c638e76152d6f3751e Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Sun, 26 Jan 2025 21:20:56 +0530 Subject: [PATCH 23/25] update two pointers links --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c38d716..8d2a4bb 100644 --- a/README.md +++ b/README.md @@ -42,14 +42,14 @@ If you want to practice curated list of LeetCode problems organized by patterns, ## 🚀 Patterns - [15 Leetcode Patterns](https://blog.algomaster.io/p/15-leetcode-patterns) - [20 DP Patterns](https://blog.algomaster.io/p/20-patterns-to-master-dynamic-programming) +- [Two Pointers Pattern](https://www.youtube.com/watch?v=QzZ7nmouLTI) +- [Sliding Window Pattern](https://blog.algomaster.io/p/f4412a17-7a3a-4d0b-8e39-9ea8f429bf7c) - [Prefix Sum Pattern](https://www.youtube.com/watch?v=yuws7YK0Yng) -- [Top 'K' Elements Pattern](https://www.youtube.com/watch?v=6_v6OoxvMOE) - [Fast and Slow Pointers Pattern](https://www.youtube.com/watch?v=b139yf7Ik-E) +- [Top 'K' Elements Pattern](https://www.youtube.com/watch?v=6_v6OoxvMOE) - [Kadane's Algorithm](https://www.youtube.com/watch?v=NUWAXbSlsws) - [Sliding Window Pattern](https://www.youtube.com/watch?v=y2d0VHdvfdc) -- [Two Pointers Pattern](https://blog.algomaster.io/p/69025a2e-b0d5-4705-8507-bba16c2691f1) - [Linked List In-place Reversal Pattern](https://www.youtube.com/watch?v=auoTGovuo9A) -- [Sliding Window Pattern](https://blog.algomaster.io/p/f4412a17-7a3a-4d0b-8e39-9ea8f429bf7c) - [Monotonic Stack Pattern](https://www.youtube.com/watch?v=DtJVwbbicjQ) - [Overlapping Intervals Pattern](https://blog.algomaster.io/p/812e72f7-eced-4256-a4c1-00606ae50679) - [Backtracking Pattern](https://blog.algomaster.io/p/81d42ca2-600c-4252-aa33-a56462090048) From ab5aff1809fedcf72a499a378eed916cdb11f259 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Fri, 21 Feb 2025 18:11:01 +0530 Subject: [PATCH 24/25] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8d2a4bb..44bee45 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,9 @@ This repository contains awesome LeetCode resources to learn Data Structures and If you want to practice curated list of LeetCode problems organized by patterns, checkout [AlgoMaster.io](https://algomaster.io) ## 💡 Tips -- [How to Start LeetCode](https://blog.algomaster.io/p/how-to-start-leetcode-in-2025) - [How I Mastered DSA](https://blog.algomaster.io/p/how-i-mastered-data-structures-and-algorithms) +- [How to Start LeetCode](https://blog.algomaster.io/p/how-to-start-leetcode-in-2025) +- [15 Leetcode Patterns](https://blog.algomaster.io/p/15-leetcode-patterns) ## 📌 Fundamental Concepts - [Algorithmic Complexity](https://blog.algomaster.io/p/57bd4963-462f-4294-a972-4012691fc729) From a404f08093b9786c7af02f3ccc800d3dff219e6e Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Sat, 1 Mar 2025 02:39:27 +0530 Subject: [PATCH 25/25] Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 44bee45..2ea2fc4 100644 --- a/README.md +++ b/README.md @@ -111,3 +111,9 @@ If you want to practice curated list of LeetCode problems organized by patterns, - [LeetCode VS Code Extension](https://marketplace.visualstudio.com/items?itemName=LeetCode.vscode-leetcode): Solve LeetCode problems in VS Code. Your contributions are most welcome! + +--- + +

+ If you find this resource helpful, please give it a star ⭐️ and share it with others! +