From 3c9300f1141b889cb58424feaa1af0e83a03b865 Mon Sep 17 00:00:00 2001 From: Sri Hari Date: Tue, 9 Sep 2025 20:36:56 +0530 Subject: [PATCH 1/9] Added articles --- articles/binary-subarrays-with-sum.md | 86 ++++++++++++ articles/find-the-difference.md | 100 ++++++++++++++ articles/fruit-into-baskets.md | 120 +++++++++++++++++ .../largest-3-same-digit-number-in-string.md | 57 ++++++++ articles/new-21-game.md | 108 +++++++++++++++ articles/rotate-list.md | 125 ++++++++++++++++++ articles/ugly-number.md | 19 +++ 7 files changed, 615 insertions(+) diff --git a/articles/binary-subarrays-with-sum.md b/articles/binary-subarrays-with-sum.md index e6b42256d..46e4ce692 100644 --- a/articles/binary-subarrays-with-sum.md +++ b/articles/binary-subarrays-with-sum.md @@ -84,6 +84,26 @@ class Solution { } ``` +```csharp +public class Solution { + public int NumSubarraysWithSum(int[] nums, int goal) { + int n = nums.Length, res = 0; + + for (int i = 0; i < n; i++) { + int curSum = 0; + for (int j = i; j < n; j++) { + curSum += nums[j]; + if (curSum == goal) { + res++; + } + } + } + + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -173,6 +193,29 @@ class Solution { } ``` +```csharp +public class Solution { + public int NumSubarraysWithSum(int[] nums, int goal) { + int prefixSum = 0, res = 0; + Dictionary count = new Dictionary(); + count[0] = 1; + + foreach (int num in nums) { + prefixSum += num; + if (count.ContainsKey(prefixSum - goal)) { + res += count[prefixSum - goal]; + } + if (!count.ContainsKey(prefixSum)) { + count[prefixSum] = 0; + } + count[prefixSum]++; + } + + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -271,6 +314,27 @@ class Solution { } ``` +```csharp +public class Solution { + public int NumSubarraysWithSum(int[] nums, int goal) { + int n = nums.Length; + int[] count = new int[n + 1]; + count[0] = 1; + int prefixSum = 0, res = 0; + + foreach (int num in nums) { + prefixSum += num; + if (prefixSum >= goal) { + res += count[prefixSum - goal]; + } + count[prefixSum]++; + } + + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -377,6 +441,28 @@ class Solution { } ``` +```csharp +public class Solution { + public int NumSubarraysWithSum(int[] nums, int goal) { + int Helper(int x) { + if (x < 0) return 0; + int res = 0, l = 0, cur = 0; + for (int r = 0; r < nums.Length; r++) { + cur += nums[r]; + while (cur > x) { + cur -= nums[l]; + l++; + } + res += (r - l + 1); + } + return res; + } + + return Helper(goal) - Helper(goal - 1); + } +} +``` + ::tabs-end ### Time & Space Complexity diff --git a/articles/find-the-difference.md b/articles/find-the-difference.md index 1b3f9f9da..669f50a12 100644 --- a/articles/find-the-difference.md +++ b/articles/find-the-difference.md @@ -73,6 +73,25 @@ class Solution { } ``` +```csharp +public class Solution { + public char FindTheDifference(string s, string t) { + int[] countS = new int[26]; + int[] countT = new int[26]; + + foreach (char c in s) countS[c - 'a']++; + foreach (char c in t) countT[c - 'a']++; + + for (int i = 0; i < 26; i++) { + if (countT[i] > countS[i]) { + return (char)(i + 'a'); + } + } + return ' '; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -157,6 +176,24 @@ class Solution { } ``` +```csharp +public class Solution { + public char FindTheDifference(string s, string t) { + int[] count = new int[26]; + + foreach (char c in t) count[c - 'a']++; + foreach (char c in s) count[c - 'a']--; + + for (int i = 0; i < 26; i++) { + if (count[i] == 1) { + return (char)(i + 'a'); + } + } + return ' '; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -233,6 +270,24 @@ class Solution { } ``` +```csharp +public class Solution { + public char FindTheDifference(string s, string t) { + char[] sArr = s.ToCharArray(); + char[] tArr = t.ToCharArray(); + Array.Sort(sArr); + Array.Sort(tArr); + + for (int i = 0; i < sArr.Length; i++) { + if (sArr[i] != tArr[i]) { + return tArr[i]; + } + } + return tArr[tArr.Length - 1]; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -309,6 +364,21 @@ class Solution { } ``` +```csharp +public class Solution { + public char FindTheDifference(string s, string t) { + int sumS = 0, sumT = 0; + for (int i = 0; i < s.Length; i++) { + sumS += s[i]; + } + for (int i = 0; i < t.Length; i++) { + sumT += t[i]; + } + return (char)(sumT - sumS); + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -384,6 +454,21 @@ class Solution { } ``` +```csharp +public class Solution { + public char FindTheDifference(string s, string t) { + int res = 0; + for (int i = 0; i < s.Length; i++) { + res -= s[i]; + } + for (int i = 0; i < t.Length; i++) { + res += t[i]; + } + return (char)res; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -459,6 +544,21 @@ class Solution { } ``` +```csharp +public class Solution { + public char FindTheDifference(string s, string t) { + int res = 0; + for (int i = 0; i < s.Length; i++) { + res ^= s[i]; + } + for (int i = 0; i < t.Length; i++) { + res ^= t[i]; + } + return (char)res; + } +} +``` + ::tabs-end ### Time & Space Complexity diff --git a/articles/fruit-into-baskets.md b/articles/fruit-into-baskets.md index 9869c7d83..d5f2a7f73 100644 --- a/articles/fruit-into-baskets.md +++ b/articles/fruit-into-baskets.md @@ -86,6 +86,26 @@ class Solution { } ``` +```csharp +public class Solution { + public int TotalFruit(int[] fruits) { + int n = fruits.Length; + int res = 0; + + for (int i = 0; i < n; i++) { + HashSet types = new HashSet(); + int j = i; + while (j < n && (types.Count < 2 || types.Contains(fruits[j]))) { + types.Add(fruits[j]); + j++; + } + res = Math.Max(res, j - i); + } + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -207,6 +227,36 @@ class Solution { } ``` +```csharp +public class Solution { + public int TotalFruit(int[] fruits) { + Dictionary count = new Dictionary(); + int l = 0, total = 0, res = 0; + + for (int r = 0; r < fruits.Length; r++) { + if (!count.ContainsKey(fruits[r])) { + count[fruits[r]] = 0; + } + count[fruits[r]]++; + total++; + + while (count.Count > 2) { + int f = fruits[l]; + count[f]--; + total--; + if (count[f] == 0) { + count.Remove(f); + } + l++; + } + + res = Math.Max(res, total); + } + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -312,6 +362,32 @@ class Solution { } ``` +```csharp +public class Solution { + public int TotalFruit(int[] fruits) { + Dictionary count = new Dictionary(); + int l = 0; + + for (int r = 0; r < fruits.Length; r++) { + if (!count.ContainsKey(fruits[r])) { + count[fruits[r]] = 0; + } + count[fruits[r]]++; + + if (count.Count > 2) { + count[fruits[l]]--; + if (count[fruits[l]] == 0) { + count.Remove(fruits[l]); + } + l++; + } + } + + return fruits.Length - l; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -473,6 +549,50 @@ class Solution { } ``` +```csharp +public class Solution { + public int TotalFruit(int[] fruits) { + int l = 0; + int fruit1_lastIdx = 0; + int fruit2_lastIdx = -1; + int fruit1 = fruits[0]; + int fruit2 = -1; + int total = 1; + int res = 1; + + for (int r = 0; r < fruits.Length; r++) { + int f = fruits[r]; + if (f == fruit1) { + total++; + fruit1_lastIdx = r; + } else if (f == fruit2 || fruit2 == -1) { + total++; + fruit2_lastIdx = r; + fruit2 = f; + } else { + if (fruit2_lastIdx == Math.Min(fruit1_lastIdx, fruit2_lastIdx)) { + int tempIdx = fruit1_lastIdx; + fruit1_lastIdx = fruit2_lastIdx; + fruit2_lastIdx = tempIdx; + + int tempFruit = fruit1; + fruit1 = fruit2; + fruit2 = tempFruit; + } + + total -= (fruit1_lastIdx - l + 1); + l = fruit1_lastIdx + 1; + fruit1 = f; + fruit1_lastIdx = r; + } + res = Math.Max(res, r - l + 1); + } + + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity diff --git a/articles/largest-3-same-digit-number-in-string.md b/articles/largest-3-same-digit-number-in-string.md index 003c5690a..3f6878d35 100644 --- a/articles/largest-3-same-digit-number-in-string.md +++ b/articles/largest-3-same-digit-number-in-string.md @@ -87,6 +87,28 @@ class Solution { } ``` +```csharp +public class Solution { + public string LargestGoodInteger(string num) { + string res = ""; + int val = 0; + + for (int i = 0; i < num.Length - 2; i++) { + if (num[i] == num[i + 1] && num[i] == num[i + 2]) { + string tmp = num.Substring(i, 3); + int tmpVal = int.Parse(tmp); + if (val <= tmpVal) { + val = tmpVal; + res = tmp; + } + } + } + + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -169,6 +191,25 @@ class Solution { } ``` +```csharp +public class Solution { + public string LargestGoodInteger(string num) { + string res = "0"; + + for (int i = 0; i < num.Length - 2; i++) { + if (num[i] == num[i + 1] && num[i] == num[i + 2]) { + string tmp = num.Substring(i, 3); + if (string.Compare(tmp, res) > 0) { + res = tmp; + } + } + } + + return res == "0" ? "" : res; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -247,6 +288,22 @@ class Solution { } ``` +```csharp +public class Solution { + public string LargestGoodInteger(string num) { + int res = -1; + + for (int i = 0; i < num.Length - 2; i++) { + if (num[i] == num[i + 1] && num[i] == num[i + 2]) { + res = Math.Max(res, num[i] - '0'); + } + } + + return res == -1 ? "" : new string((char)(res + '0'), 3); + } +} +``` + ::tabs-end ### Time & Space Complexity diff --git a/articles/new-21-game.md b/articles/new-21-game.md index 5d0bb1eb2..babfd124b 100644 --- a/articles/new-21-game.md +++ b/articles/new-21-game.md @@ -116,6 +116,35 @@ class Solution { } ``` +```csharp +public class Solution { + private double[] dp; + + public double New21Game(int n, int k, int maxPts) { + dp = new double[k]; + for (int i = 0; i < dp.Length; i++) dp[i] = -1.0; + return Dfs(0, n, k, maxPts); + } + + private double Dfs(int score, int n, int k, int maxPts) { + if (score >= k) { + return score <= n ? 1.0 : 0.0; + } + if (dp[score] != -1.0) { + return dp[score]; + } + + double prob = 0; + for (int i = 1; i <= maxPts; i++) { + prob += Dfs(score + i, n, k, maxPts); + } + + dp[score] = prob / maxPts; + return dp[score]; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -253,6 +282,37 @@ class Solution { } ``` +```csharp +public class Solution { + private double[] dp; + + public double New21Game(int n, int k, int maxPts) { + dp = new double[k + maxPts]; + for (int i = 0; i < dp.Length; i++) dp[i] = -1.0; + return Dfs(0, n, k, maxPts); + } + + private double Dfs(int score, int n, int k, int maxPts) { + if (score == k - 1) { + return Math.Min(n - k + 1, maxPts) / (double)maxPts; + } + if (score > n) { + return 0.0; + } + if (score >= k) { + return 1.0; + } + if (dp[score] != -1.0) { + return dp[score]; + } + + dp[score] = Dfs(score + 1, n, k, maxPts); + dp[score] -= (Dfs(score + 1 + maxPts, n, k, maxPts) - Dfs(score + 1, n, k, maxPts)) / maxPts; + return dp[score]; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -361,6 +421,30 @@ class Solution { } ``` +```csharp +public class Solution { + public double New21Game(int n, int k, int maxPts) { + double[] dp = new double[n + 1]; + dp[0] = 1.0; + + for (int score = 1; score <= n; score++) { + for (int draw = 1; draw <= maxPts; draw++) { + if (score - draw >= 0 && score - draw < k) { + dp[score] += dp[score - draw] / maxPts; + } + } + } + + double result = 0.0; + for (int i = k; i <= n; i++) { + result += dp[i]; + } + + return result; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -475,6 +559,30 @@ class Solution { } ``` +```csharp +public class Solution { + public double New21Game(int n, int k, int maxPts) { + if (k == 0) { + return 1.0; + } + double windowSum = 0.0; + for (int i = k; i < k + maxPts; i++) { + windowSum += (i <= n) ? 1.0 : 0.0; + } + Dictionary dp = new Dictionary(); + for (int i = k - 1; i >= 0; i--) { + dp[i] = windowSum / maxPts; + double remove = 0.0; + if (i + maxPts <= n) { + remove = dp.ContainsKey(i + maxPts) ? dp[i + maxPts] : 1.0; + } + windowSum += dp[i] - remove; + } + return dp[0]; + } +} +``` + ::tabs-end ### Time & Space Complexity diff --git a/articles/rotate-list.md b/articles/rotate-list.md index a954129f6..fd9024ef0 100644 --- a/articles/rotate-list.md +++ b/articles/rotate-list.md @@ -151,6 +151,49 @@ class Solution { } ``` +```csharp +/** + * Definition for singly-linked list. + * 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 RotateRight(ListNode head, int k) { + if (head == null) { + return null; + } + + List arr = new List(); + ListNode cur = head; + while (cur != null) { + arr.Add(cur.val); + cur = cur.next; + } + + int n = arr.Count; + k %= n; + cur = head; + for (int i = n - k; i < n; i++) { + cur.val = arr[i]; + cur = cur.next; + } + + for (int i = 0; i < n - k; i++) { + cur.val = arr[i]; + cur = cur.next; + } + + return head; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -325,6 +368,50 @@ class Solution { } ``` +```csharp +/** + * Definition for singly-linked list. + * 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 RotateRight(ListNode head, int k) { + if (head == null) { + return head; + } + + int length = 1; + ListNode tail = head; + while (tail.next != null) { + tail = tail.next; + length++; + } + + k = k % length; + if (k == 0) { + return head; + } + + ListNode cur = head; + for (int i = 0; i < length - k - 1; i++) { + cur = cur.next; + } + + ListNode newHead = cur.next; + cur.next = null; + tail.next = head; + + return newHead; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -480,6 +567,44 @@ class Solution { } ``` +```csharp +/** + * Definition for singly-linked list. + * 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 RotateRight(ListNode head, int k) { + if (head == null) { + return head; + } + + ListNode cur = head; + int n = 1; + while (cur.next != null) { + n++; + cur = cur.next; + } + + cur.next = head; + k %= n; + for (int i = 0; i < n - k; i++) { + cur = cur.next; + } + + head = cur.next; + cur.next = null; + return head; + } +} +``` + ::tabs-end ### Time & Space Complexity diff --git a/articles/ugly-number.md b/articles/ugly-number.md index f389b697d..69862de7c 100644 --- a/articles/ugly-number.md +++ b/articles/ugly-number.md @@ -68,6 +68,25 @@ class Solution { } ``` +```csharp +public class Solution { + public bool IsUgly(int n) { + if (n <= 0) { + return false; + } + + int[] primes = { 2, 3, 5 }; + foreach (int p in primes) { + while (n % p == 0) { + n /= p; + } + } + + return n == 1; + } +} +``` + ::tabs-end ### Time & Space Complexity From afe311fe06697c27b40e6b1bdc0002a559e8f880 Mon Sep 17 00:00:00 2001 From: Sri Hari Date: Sun, 14 Sep 2025 22:33:02 +0530 Subject: [PATCH 2/9] Added articles --- articles/bus-routes.md | 503 ++++++++++ articles/cherry-pickup.md | 937 ++++++++++++++++++ ...ng-with-at-most-two-distinct-characters.md | 373 +++++++ .../subarrays-with-k-different-integers.md | 131 +++ 4 files changed, 1944 insertions(+) create mode 100644 articles/bus-routes.md create mode 100644 articles/cherry-pickup.md create mode 100644 articles/longest-substring-with-at-most-two-distinct-characters.md diff --git a/articles/bus-routes.md b/articles/bus-routes.md new file mode 100644 index 000000000..c56846c39 --- /dev/null +++ b/articles/bus-routes.md @@ -0,0 +1,503 @@ +## 1. Breadth First Search (Stops as Nodes) + +::tabs-start + +```python +class Solution: + def numBusesToDestination(self, routes: List[List[int]], source: int, target: int) -> int: + if source == target: + return 0 + + n = len(routes) + stops = defaultdict(list) + for bus in range(n): + for stop in routes[bus]: + stops[stop].append(bus) + + seen_bus = set() + seen_stop = set([source]) + res = 0 + q = deque([source]) + while q: + for _ in range(len(q)): + stop = q.popleft() + if stop == target: + return res + for bus in stops[stop]: + if bus in seen_bus: + continue + seen_bus.add(bus) + for nxtStop in routes[bus]: + if nxtStop in seen_stop: + continue + seen_stop.add(nxtStop) + q.append(nxtStop) + res += 1 + + return -1 +``` + +```java +public class Solution { + public int numBusesToDestination(int[][] routes, int source, int target) { + if (source == target) return 0; + int n = routes.length; + Map> stops = new HashMap<>(); + for (int bus = 0; bus < n; bus++) { + for (int stop : routes[bus]) { + stops.computeIfAbsent(stop, k -> new ArrayList<>()).add(bus); + } + } + + Set seenBus = new HashSet<>(); + Set seenStop = new HashSet<>(); + seenStop.add(source); + Queue q = new LinkedList<>(); + q.add(source); + int res = 0; + + while (!q.isEmpty()) { + int size = q.size(); + for (int k = 0; k < size; k++) { + int stop = q.poll(); + if (stop == target) return res; + for (int bus : stops.getOrDefault(stop, new ArrayList<>())) { + if (seenBus.contains(bus)) continue; + seenBus.add(bus); + for (int nxtStop : routes[bus]) { + if (seenStop.contains(nxtStop)) continue; + seenStop.add(nxtStop); + q.add(nxtStop); + } + } + } + res++; + } + return -1; + } +} +``` + +```cpp +class Solution { +public: + int numBusesToDestination(vector>& routes, int source, int target) { + if (source == target) return 0; + int n = routes.size(); + unordered_map> stops; + for (int bus = 0; bus < n; bus++) { + for (int stop : routes[bus]) { + stops[stop].push_back(bus); + } + } + + unordered_set seenBus; + unordered_set seenStop; + seenStop.insert(source); + queue q; + q.push(source); + int res = 0; + + while (!q.empty()) { + int size = q.size(); + for (int k = 0; k < size; k++) { + int stop = q.front(); q.pop(); + if (stop == target) return res; + for (int bus : stops[stop]) { + if (seenBus.count(bus)) continue; + seenBus.insert(bus); + for (int nxtStop : routes[bus]) { + if (seenStop.count(nxtStop)) continue; + seenStop.insert(nxtStop); + q.push(nxtStop); + } + } + } + res++; + } + return -1; + } +}; +``` + +```javascript +class Solution { + /** + * @param {number[][]} routes + * @param {number} source + * @param {number} target + * @return {number} + */ + numBusesToDestination(routes, source, target) { + if (source === target) return 0; + let n = routes.length; + let stops = new Map(); + for (let bus = 0; bus < n; bus++) { + for (let stop of routes[bus]) { + if (!stops.has(stop)) stops.set(stop, []); + stops.get(stop).push(bus); + } + } + + let seenBus = new Set(); + let seenStop = new Set([source]); + let q = new Queue([source]); + let res = 0; + + while (!q.isEmpty()) { + let size = q.size(); + for (let k = 0; k < size; k++) { + let stop = q.pop(); + if (stop === target) return res; + for (let bus of (stops.get(stop) || [])) { + if (seenBus.has(bus)) continue; + seenBus.add(bus); + for (let nxtStop of routes[bus]) { + if (seenStop.has(nxtStop)) continue; + seenStop.add(nxtStop); + q.push(nxtStop); + } + } + } + res++; + } + return -1; + } +} +``` + +```csharp +public class Solution { + public int NumBusesToDestination(int[][] routes, int source, int target) { + if (source == target) return 0; + int n = routes.Length; + var stops = new Dictionary>(); + for (int bus = 0; bus < n; bus++) { + foreach (int stop in routes[bus]) { + if (!stops.ContainsKey(stop)) stops[stop] = new List(); + stops[stop].Add(bus); + } + } + + var seenBus = new HashSet(); + var seenStop = new HashSet { source }; + Queue q = new Queue(); + q.Enqueue(source); + int res = 0; + + while (q.Count > 0) { + int size = q.Count; + for (int k = 0; k < size; k++) { + int stop = q.Dequeue(); + if (stop == target) return res; + foreach (int bus in stops.GetValueOrDefault(stop, new List())) { + if (seenBus.Contains(bus)) continue; + seenBus.Add(bus); + foreach (int nxtStop in routes[bus]) { + if (seenStop.Contains(nxtStop)) continue; + seenStop.Add(nxtStop); + q.Enqueue(nxtStop); + } + } + } + res++; + } + return -1; + } +} +``` + +::tabs-end + +### Time & Space Complexity + +* Time complexity: $O(n * m)$ +* Space complexity: $O(n * m)$ + +> Where $n$ is the number of routes and $m$ is the maximum number of stops per bus route. + +--- + +## 2. Breadth First Search (Routes as Nodes) + +::tabs-start + +```python +class Solution: + def numBusesToDestination(self, routes: List[List[int]], source: int, target: int) -> int: + if source == target: + return 0 + + n = len(routes) + adjList = [[] for _ in range(n)] + stopToRoutes = defaultdict(list) + for bus, route in enumerate(routes): + for stop in route: + stopToRoutes[stop].append(bus) + + if target not in stopToRoutes or source not in stopToRoutes: + return -1 + + hasEdge = [[False] * n for _ in range(n)] + for buses in stopToRoutes.values(): + for i in range(len(buses)): + for j in range(i + 1, len(buses)): + if hasEdge[buses[i]][buses[j]]: + continue + hasEdge[buses[i]][buses[j]] = True + hasEdge[buses[j]][buses[i]] = True + adjList[buses[i]].append(buses[j]) + adjList[buses[j]].append(buses[i]) + + q = deque([node for node in stopToRoutes[source]]) + res = 1 + while q: + for _ in range(len(q)): + node = q.popleft() + if node in stopToRoutes[target]: + return res + while adjList[node]: + nxtBus = adjList[node].pop() + if adjList[nxtBus]: + q.append(nxtBus) + res += 1 + + return -1 +``` + +```java +class Solution { + public int numBusesToDestination(int[][] routes, int source, int target) { + if (source == target) return 0; + + int n = routes.length; + List> adjList = new ArrayList<>(); + for (int i = 0; i < n; i++) adjList.add(new ArrayList<>()); + Map> stopToRoutes = new HashMap<>(); + + for (int bus = 0; bus < n; bus++) { + for (int stop : routes[bus]) { + stopToRoutes.computeIfAbsent(stop, k -> new ArrayList<>()).add(bus); + } + } + + if (!stopToRoutes.containsKey(source) || !stopToRoutes.containsKey(target)) { + return -1; + } + + boolean[][] hasEdge = new boolean[n][n]; + for (List buses : stopToRoutes.values()) { + for (int i = 0; i < buses.size(); i++) { + for (int j = i + 1; j < buses.size(); j++) { + int b1 = buses.get(i), b2 = buses.get(j); + if (!hasEdge[b1][b2]) { + hasEdge[b1][b2] = true; + hasEdge[b2][b1] = true; + adjList.get(b1).add(b2); + adjList.get(b2).add(b1); + } + } + } + } + + Queue q = new LinkedList<>(); + for (int bus : stopToRoutes.get(source)) q.add(bus); + + int res = 1; + while (!q.isEmpty()) { + for (int k = q.size(); k >= 1; k--) { + int node = q.poll(); + if (stopToRoutes.get(target).contains(node)) return res; + while (!adjList.get(node).isEmpty()) { + int nxtBus = adjList.get(node).remove(adjList.get(node).size() - 1); + if (!adjList.get(nxtBus).isEmpty()) { + q.add(nxtBus); + } + } + } + res++; + } + return -1; + } +} +``` + +```cpp +class Solution { +public: + int numBusesToDestination(vector>& routes, int source, int target) { + if (source == target) return 0; + + int n = routes.size(); + vector> adjList(n); + unordered_map> stopToRoutes; + for (int bus = 0; bus < n; bus++) { + for (int stop : routes[bus]) { + stopToRoutes[stop].push_back(bus); + } + } + + if (!stopToRoutes.count(source) || !stopToRoutes.count(target)) return -1; + + vector> hasEdge(n, vector(n, false)); + for (auto& [stop, buses] : stopToRoutes) { + for (int i = 0; i < (int)buses.size(); i++) { + for (int j = i + 1; j < (int)buses.size(); j++) { + int b1 = buses[i], b2 = buses[j]; + if (!hasEdge[b1][b2]) { + hasEdge[b1][b2] = hasEdge[b2][b1] = true; + adjList[b1].push_back(b2); + adjList[b2].push_back(b1); + } + } + } + } + + queue q; + for (int bus : stopToRoutes[source]) q.push(bus); + + int res = 1; + while (!q.empty()) { + int size = q.size(); + for (int k = 0; k < size; k++) { + int node = q.front(); q.pop(); + if (find(stopToRoutes[target].begin(), stopToRoutes[target].end(), node) != stopToRoutes[target].end()) { + return res; + } + while (!adjList[node].empty()) { + int nxtBus = adjList[node].back(); + adjList[node].pop_back(); + if (!adjList[nxtBus].empty()) { + q.push(nxtBus); + } + } + } + res++; + } + return -1; + } +}; +``` + +```javascript +class Solution { + /** + * @param {number[][]} routes + * @param {number} source + * @param {number} target + * @return {number} + */ + numBusesToDestination(routes, source, target) { + if (source === target) return 0; + + const n = routes.length; + const adjList = Array.from({ length: n }, () => []); + const stopToRoutes = new Map(); + for (let bus = 0; bus < n; bus++) { + for (let stop of routes[bus]) { + if (!stopToRoutes.has(stop)) stopToRoutes.set(stop, []); + stopToRoutes.get(stop).push(bus); + } + } + + if (!stopToRoutes.has(source) || !stopToRoutes.has(target)) return -1; + + const hasEdge = Array.from({ length: n }, () => Array(n).fill(false)); + for (let buses of stopToRoutes.values()) { + for (let i = 0; i < buses.length; i++) { + for (let j = i + 1; j < buses.length; j++) { + if (!hasEdge[buses[i]][buses[j]]) { + hasEdge[buses[i]][buses[j]] = true; + hasEdge[buses[j]][buses[i]] = true; + adjList[buses[i]].push(buses[j]); + adjList[buses[j]].push(buses[i]); + } + } + } + } + + const q = new Queue(stopToRoutes.get(source)); + let res = 1; + while (!q.isEmpty()) { + for (let k = q.size(); k >= 1; k--) { + const node = q.pop(); + if (stopToRoutes.get(target).includes(node)) return res; + while (adjList[node].length > 0) { + const nxtBus = adjList[node].pop(); + if (adjList[nxtBus].length > 0) { + q.push(nxtBus); + } + } + } + res++; + } + + return -1; + } +} +``` + +```csharp +public class Solution { + public int NumBusesToDestination(int[][] routes, int source, int target) { + if (source == target) return 0; + + int n = routes.Length; + var adjList = new List[n]; + for (int i = 0; i < n; i++) adjList[i] = new List(); + var stopToRoutes = new Dictionary>(); + for (int bus = 0; bus < n; bus++) { + foreach (int stop in routes[bus]) { + if (!stopToRoutes.ContainsKey(stop)) stopToRoutes[stop] = new List(); + stopToRoutes[stop].Add(bus); + } + } + + if (!stopToRoutes.ContainsKey(target) || !stopToRoutes.ContainsKey(source)) { + return -1; + } + + bool[,] hasEdge = new bool[n, n]; + foreach (var buses in stopToRoutes.Values) { + for (int i = 0; i < buses.Count; i++) { + for (int j = i + 1; j < buses.Count; j++) { + if (hasEdge[buses[i], buses[j]]) continue; + hasEdge[buses[i], buses[j]] = true; + hasEdge[buses[j], buses[i]] = true; + adjList[buses[i]].Add(buses[j]); + adjList[buses[j]].Add(buses[i]); + } + } + } + + var q = new Queue(); + foreach (int node in stopToRoutes[source]) q.Enqueue(node); + + int res = 1; + while (q.Count > 0) { + int size = q.Count; + while (size-- > 0) { + int node = q.Dequeue(); + if (stopToRoutes[target].Contains(node)) return res; + while (adjList[node].Count > 0) { + int nxtBus = adjList[node][adjList[node].Count - 1]; + adjList[node].RemoveAt(adjList[node].Count - 1); + if (adjList[nxtBus].Count > 0) q.Enqueue(nxtBus); + } + } + res++; + } + + return -1; + } +} +``` + +::tabs-end + +### Time & Space Complexity + +* Time complexity: $O(n ^ 2 + n * m)$ +* Space complexity: $O(n ^ 2 + n * m)$ + +> Where $n$ is the number of routes and $m$ is the maximum number of stops per bus route. \ No newline at end of file diff --git a/articles/cherry-pickup.md b/articles/cherry-pickup.md new file mode 100644 index 000000000..a19236ae3 --- /dev/null +++ b/articles/cherry-pickup.md @@ -0,0 +1,937 @@ +## 1. Recursion + +::tabs-start + +```python +class Solution: + def cherryPickup(self, grid: List[List[int]]) -> int: + n = len(grid) + def dfs(r1, c1, r2, c2): + if r1 >= n or c1 >= n or r2 >= n or c2 >= n or grid[r1][c1] == -1 or grid[r2][c2] == -1: + return -1000 + + if r1 == n - 1 and r2 == n - 1 and c1 == n - 1 and c2 == n - 1: + return grid[r1][c1] + + res = dfs(r1 + 1, c1, r2 + 1, c2) + res = max(res, dfs(r1 + 1, c1, r2, c2 + 1)) + res = max(res, dfs(r1, c1 + 1, r2 + 1, c2)) + res = max(res, dfs(r1, c1 + 1, r2, c2 + 1)) + res += grid[r1][c1] + grid[r2][c2] + res -= (grid[r1][c1] if (r1 == r2 and c1 == c2) else 0) + return res + + return max(0, dfs(0, 0, 0, 0)) +``` + +```java +public class Solution { + public int cherryPickup(int[][] grid) { + int n = grid.length; + return Math.max(0, dfs(0, 0, 0, 0, grid, n)); + } + + private int dfs(int r1, int c1, int r2, int c2, int[][] grid, int n) { + if (r1 >= n || c1 >= n || r2 >= n || c2 >= n || grid[r1][c1] == -1 || grid[r2][c2] == -1) + return -1000; + + if (r1 == n - 1 && c1 == n - 1 && r2 == n - 1 && c2 == n - 1) + return grid[r1][c1]; + + int res = dfs(r1 + 1, c1, r2 + 1, c2, grid, n); + res = Math.max(res, dfs(r1 + 1, c1, r2, c2 + 1, grid, n)); + res = Math.max(res, dfs(r1, c1 + 1, r2 + 1, c2, grid, n)); + res = Math.max(res, dfs(r1, c1 + 1, r2, c2 + 1, grid, n)); + res += grid[r1][c1] + grid[r2][c2]; + if (r1 == r2 && c1 == c2) res -= grid[r1][c1]; + return res; + } +} +``` + +```cpp +class Solution { +public: + int cherryPickup(vector>& grid) { + int n = grid.size(); + return max(0, dfs(0, 0, 0, 0, grid, n)); + } + + int dfs(int r1, int c1, int r2, int c2, vector>& grid, int n) { + if (r1 >= n || c1 >= n || r2 >= n || c2 >= n || grid[r1][c1] == -1 || grid[r2][c2] == -1) + return -1000; + + if (r1 == n - 1 && c1 == n - 1 && r2 == n - 1 && c2 == n - 1) + return grid[r1][c1]; + + int res = dfs(r1 + 1, c1, r2 + 1, c2, grid, n); + res = max(res, dfs(r1 + 1, c1, r2, c2 + 1, grid, n)); + res = max(res, dfs(r1, c1 + 1, r2 + 1, c2, grid, n)); + res = max(res, dfs(r1, c1 + 1, r2, c2 + 1, grid, n)); + res += grid[r1][c1] + grid[r2][c2]; + if (r1 == r2 && c1 == c2) res -= grid[r1][c1]; + return res; + } +}; +``` + +```javascript +class Solution { + /** + * @param {number[][]} grid + * @return {number} + */ + cherryPickup(grid) { + const n = grid.length; + const dfs = (r1, c1, r2, c2) => { + if (r1 >= n || c1 >= n || r2 >= n || c2 >= n || grid[r1][c1] === -1 || grid[r2][c2] === -1) + return -1000; + + if (r1 === n - 1 && c1 === n - 1 && r2 === n - 1 && c2 === n - 1) + return grid[r1][c1]; + + let res = dfs(r1 + 1, c1, r2 + 1, c2); + res = Math.max(res, dfs(r1 + 1, c1, r2, c2 + 1)); + res = Math.max(res, dfs(r1, c1 + 1, r2 + 1, c2)); + res = Math.max(res, dfs(r1, c1 + 1, r2, c2 + 1)); + res += grid[r1][c1] + grid[r2][c2]; + if (r1 === r2 && c1 === c2) res -= grid[r1][c1]; + return res; + }; + return Math.max(0, dfs(0, 0, 0, 0)); + } +} +``` + +```csharp +public class Solution { + public int CherryPickup(int[][] grid) { + int n = grid.Length; + return Math.Max(0, Dfs(0, 0, 0, 0, grid, n)); + } + + private int Dfs(int r1, int c1, int r2, int c2, int[][] grid, int n) { + if (r1 >= n || c1 >= n || r2 >= n || c2 >= n || grid[r1][c1] == -1 || grid[r2][c2] == -1) + return -1000; + + if (r1 == n - 1 && c1 == n - 1 && r2 == n - 1 && c2 == n - 1) + return grid[r1][c1]; + + int res = Dfs(r1 + 1, c1, r2 + 1, c2, grid, n); + res = Math.Max(res, Dfs(r1 + 1, c1, r2, c2 + 1, grid, n)); + res = Math.Max(res, Dfs(r1, c1 + 1, r2 + 1, c2, grid, n)); + res = Math.Max(res, Dfs(r1, c1 + 1, r2, c2 + 1, grid, n)); + res += grid[r1][c1] + grid[r2][c2]; + if (r1 == r2 && c1 == c2) res -= grid[r1][c1]; + return res; + } +} +``` + +::tabs-end + +### Time & Space Complexity + +* Time complexity: $O(16 ^ n)$ +* Space complexity: $O(n)$ for recursion stack. + +--- + +## 2. Dynamic Programming (Top-Down) + +::tabs-start + +```python +class Solution: + def cherryPickup(self, grid: List[List[int]]) -> int: + n = len(grid) + dp = [[[[float("-inf")] * n for _ in range(n)] for _ in range(n)] for _ in range(n)] + + def dfs(r1, c1, r2, c2): + if r1 >= n or c1 >= n or r2 >= n or c2 >= n or grid[r1][c1] == -1 or grid[r2][c2] == -1: + return -1000 + + if r1 == n - 1 and r2 == n - 1 and c1 == n - 1 and c2 == n - 1: + return grid[r1][c1] + + if dp[r1][c1][r2][c2] != float("-inf"): + return dp[r1][c1][r2][c2] + + res = dfs(r1 + 1, c1, r2 + 1, c2) + res = max(res, dfs(r1 + 1, c1, r2, c2 + 1)) + res = max(res, dfs(r1, c1 + 1, r2 + 1, c2)) + res = max(res, dfs(r1, c1 + 1, r2, c2 + 1)) + res += grid[r1][c1] + grid[r2][c2] + if r1 == r2 and c1 == c2: + res -= grid[r1][c1] + + dp[r1][c1][r2][c2] = res + return res + + return max(0, dfs(0, 0, 0, 0)) +``` + +```java +public class Solution { + int n; + int[][][][] dp; + int[][] grid; + + public int cherryPickup(int[][] grid) { + this.n = grid.length; + this.grid = grid; + dp = new int[n][n][n][n]; + for (int a = 0; a < n; a++) + for (int b = 0; b < n; b++) + for (int c = 0; c < n; c++) + for (int d = 0; d < n; d++) + dp[a][b][c][d] = Integer.MIN_VALUE; + return Math.max(0, dfs(0, 0, 0, 0)); + } + + private int dfs(int r1, int c1, int r2, int c2) { + if (r1 >= n || c1 >= n || r2 >= n || c2 >= n || + grid[r1][c1] == -1 || grid[r2][c2] == -1) { + return -1000; + } + if (r1 == n - 1 && c1 == n - 1 && r2 == n - 1 && c2 == n - 1) { + return grid[r1][c1]; + } + if (dp[r1][c1][r2][c2] != Integer.MIN_VALUE) { + return dp[r1][c1][r2][c2]; + } + int res = dfs(r1 + 1, c1, r2 + 1, c2); + res = Math.max(res, dfs(r1 + 1, c1, r2, c2 + 1)); + res = Math.max(res, dfs(r1, c1 + 1, r2 + 1, c2)); + res = Math.max(res, dfs(r1, c1 + 1, r2, c2 + 1)); + res += grid[r1][c1] + grid[r2][c2]; + if (r1 == r2 && c1 == c2) res -= grid[r1][c1]; + dp[r1][c1][r2][c2] = res; + return res; + } +} +``` + +```cpp +class Solution { +public: + int n; + vector>>> dp; + vector> grid; + + int cherryPickup(vector>& grid) { + this->n = grid.size(); + this->grid = grid; + dp = vector(n, vector(n, vector(n, vector(n, INT_MIN)))); + return max(0, dfs(0, 0, 0, 0)); + } + + int dfs(int r1, int c1, int r2, int c2) { + if (r1 >= n || c1 >= n || r2 >= n || c2 >= n || + grid[r1][c1] == -1 || grid[r2][c2] == -1) { + return -1000; + } + if (r1 == n - 1 && c1 == n - 1 && r2 == n - 1 && c2 == n - 1) { + return grid[r1][c1]; + } + if (dp[r1][c1][r2][c2] != INT_MIN) { + return dp[r1][c1][r2][c2]; + } + int res = dfs(r1 + 1, c1, r2 + 1, c2); + res = max(res, dfs(r1 + 1, c1, r2, c2 + 1)); + res = max(res, dfs(r1, c1 + 1, r2 + 1, c2)); + res = max(res, dfs(r1, c1 + 1, r2, c2 + 1)); + res += grid[r1][c1] + grid[r2][c2]; + if (r1 == r2 && c1 == c2) res -= grid[r1][c1]; + return dp[r1][c1][r2][c2] = res; + } +}; +``` + +```javascript +class Solution { + /** + * @param {number[][]} grid + * @return {number} + */ + cherryPickup(grid) { + const n = grid.length; + const dp = Array.from({ length: n }, () => + Array.from({ length: n }, () => + Array.from({ length: n }, () => + Array(n).fill(-Infinity) + ) + ) + ); + + const dfs = (r1, c1, r2, c2) => { + if (r1 >= n || c1 >= n || r2 >= n || c2 >= n || + grid[r1][c1] === -1 || grid[r2][c2] === -1) { + return -1000; + } + if (r1 === n - 1 && c1 === n - 1 && r2 === n - 1 && c2 === n - 1) { + return grid[r1][c1]; + } + if (dp[r1][c1][r2][c2] !== -Infinity) { + return dp[r1][c1][r2][c2]; + } + + let res = dfs(r1 + 1, c1, r2 + 1, c2); + res = Math.max(res, dfs(r1 + 1, c1, r2, c2 + 1)); + res = Math.max(res, dfs(r1, c1 + 1, r2 + 1, c2)); + res = Math.max(res, dfs(r1, c1 + 1, r2, c2 + 1)); + res += grid[r1][c1] + grid[r2][c2]; + if (r1 === r2 && c1 === c2) res -= grid[r1][c1]; + + dp[r1][c1][r2][c2] = res; + return res; + }; + + return Math.max(0, dfs(0, 0, 0, 0)); + } +} +``` + +```csharp +public class Solution { + int n; + int[,,,] dp; + int[][] grid; + + public int CherryPickup(int[][] grid) { + n = grid.Length; + this.grid = grid; + dp = new int[n,n,n,n]; + for (int a = 0; a < n; a++) + for (int b = 0; b < n; b++) + for (int c = 0; c < n; c++) + for (int d = 0; d < n; d++) + dp[a,b,c,d] = int.MinValue; + return Math.Max(0, Dfs(0, 0, 0, 0)); + } + + private int Dfs(int r1, int c1, int r2, int c2) { + if (r1 >= n || c1 >= n || r2 >= n || c2 >= n || + grid[r1][c1] == -1 || grid[r2][c2] == -1) { + return -1000; + } + if (r1 == n - 1 && c1 == n - 1 && r2 == n - 1 && c2 == n - 1) { + return grid[r1][c1]; + } + if (dp[r1,c1,r2,c2] != int.MinValue) { + return dp[r1,c1,r2,c2]; + } + int res = Dfs(r1 + 1, c1, r2 + 1, c2); + res = Math.Max(res, Dfs(r1 + 1, c1, r2, c2 + 1)); + res = Math.Max(res, Dfs(r1, c1 + 1, r2 + 1, c2)); + res = Math.Max(res, Dfs(r1, c1 + 1, r2, c2 + 1)); + res += grid[r1][c1] + grid[r2][c2]; + if (r1 == r2 && c1 == c2) res -= grid[r1][c1]; + dp[r1,c1,r2,c2] = res; + return res; + } +} +``` + +::tabs-end + +### Time & Space Complexity + +* Time complexity: $O(n ^ 4)$ +* Space complexity: $O(n ^ 4)$ + +--- + +## 3. Dynamic Programming (Top-Down) Optimized + +::tabs-start + +```python +class Solution: + def cherryPickup(self, grid: List[List[int]]) -> int: + n = len(grid) + dp = [[[float("-inf")] * n for _ in range(n)] for _ in range(n)] + + def dfs(r1, c1, r2): + c2 = r1 + c1 - r2 + if r1 >= n or c1 >= n or r2 >= n or c2 >= n or grid[r1][c1] == -1 or grid[r2][c2] == -1: + return -1000 + + if r1 == n - 1 and c1 == n - 1: + return grid[r1][c1] + + if dp[r1][c1][r2] != float("-inf"): + return dp[r1][c1][r2] + + res = dfs(r1 + 1, c1, r2 + 1) + res = max(res, dfs(r1 + 1, c1, r2)) + res = max(res, dfs(r1, c1 + 1, r2 + 1)) + res = max(res, dfs(r1, c1 + 1, r2)) + res += grid[r1][c1] + if (r1, c1) != (r2, c2): + res += grid[r2][c2] + + dp[r1][c1][r2] = res + return res + + return max(0, dfs(0, 0, 0)) +``` + +```java +public class Solution { + int[][][] dp; + int[][] grid; + int n; + + public int cherryPickup(int[][] grid) { + this.n = grid.length; + this.grid = grid; + dp = new int[n][n][n]; + for (int i = 0; i < n; i++) + for (int j = 0; j < n; j++) + for (int k = 0; k < n; k++) + dp[i][j][k] = Integer.MIN_VALUE; + + return Math.max(0, dfs(0, 0, 0)); + } + + private int dfs(int r1, int c1, int r2) { + int c2 = r1 + c1 - r2; + if (r1 >= n || c1 >= n || r2 >= n || c2 >= n || grid[r1][c1] == -1 || grid[r2][c2] == -1) + return -1000; + + if (r1 == n - 1 && c1 == n - 1) + return grid[r1][c1]; + + if (dp[r1][c1][r2] != Integer.MIN_VALUE) + return dp[r1][c1][r2]; + + int res = dfs(r1 + 1, c1, r2 + 1); + res = Math.max(res, dfs(r1 + 1, c1, r2)); + res = Math.max(res, dfs(r1, c1 + 1, r2 + 1)); + res = Math.max(res, dfs(r1, c1 + 1, r2)); + + res += grid[r1][c1]; + if (!(r1 == r2 && c1 == c2)) res += grid[r2][c2]; + + return dp[r1][c1][r2] = res; + } +} +``` + +```cpp +class Solution { + vector>> dp; + vector> grid; + int n; + +public: + int cherryPickup(vector>& grid) { + this->n = grid.size(); + this->grid = grid; + dp.assign(n, vector>(n, vector(n, INT_MIN))); + return max(0, dfs(0, 0, 0)); + } + + int dfs(int r1, int c1, int r2) { + int c2 = r1 + c1 - r2; + if (r1 >= n || c1 >= n || r2 >= n || c2 >= n || grid[r1][c1] == -1 || grid[r2][c2] == -1) + return -1000; + + if (r1 == n - 1 && c1 == n - 1) + return grid[r1][c1]; + + if (dp[r1][c1][r2] != INT_MIN) + return dp[r1][c1][r2]; + + int res = dfs(r1 + 1, c1, r2 + 1); + res = max(res, dfs(r1 + 1, c1, r2)); + res = max(res, dfs(r1, c1 + 1, r2 + 1)); + res = max(res, dfs(r1, c1 + 1, r2)); + + res += grid[r1][c1]; + if (!(r1 == r2 && c1 == c2)) res += grid[r2][c2]; + + return dp[r1][c1][r2] = res; + } +}; +``` + +```javascript +class Solution { + /** + * @param {number[][]} grid + * @return {number} + */ + cherryPickup(grid) { + const n = grid.length; + const dp = Array.from({ length: n }, () => + Array.from({ length: n }, () => + Array(n).fill(-Infinity) + ) + ); + + const dfs = (r1, c1, r2) => { + const c2 = r1 + c1 - r2; + if (r1 >= n || c1 >= n || r2 >= n || c2 >= n || grid[r1][c1] === -1 || grid[r2][c2] === -1) + return -1000; + + if (r1 === n - 1 && c1 === n - 1) + return grid[r1][c1]; + + if (dp[r1][c1][r2] !== -Infinity) + return dp[r1][c1][r2]; + + let res = dfs(r1 + 1, c1, r2 + 1); + res = Math.max(res, dfs(r1 + 1, c1, r2)); + res = Math.max(res, dfs(r1, c1 + 1, r2 + 1)); + res = Math.max(res, dfs(r1, c1 + 1, r2)); + + res += grid[r1][c1]; + if (!(r1 === r2 && c1 === c2)) res += grid[r2][c2]; + + return dp[r1][c1][r2] = res; + }; + + return Math.max(0, dfs(0, 0, 0)); + } +} +``` + +```csharp +public class Solution { + private int[,,] dp; + private int[][] grid; + private int n; + + public int CherryPickup(int[][] grid) { + this.n = grid.Length; + this.grid = grid; + dp = new int[n, n, n]; + for (int i = 0; i < n; i++) + for (int j = 0; j < n; j++) + for (int k = 0; k < n; k++) + dp[i, j, k] = int.MinValue; + + return Math.Max(0, Dfs(0, 0, 0)); + } + + private int Dfs(int r1, int c1, int r2) { + int c2 = r1 + c1 - r2; + if (r1 >= n || c1 >= n || r2 >= n || c2 >= n || grid[r1][c1] == -1 || grid[r2][c2] == -1) + return -1000; + + if (r1 == n - 1 && c1 == n - 1) + return grid[r1][c1]; + + if (dp[r1, c1, r2] != int.MinValue) + return dp[r1, c1, r2]; + + int res = Dfs(r1 + 1, c1, r2 + 1); + res = Math.Max(res, Dfs(r1 + 1, c1, r2)); + res = Math.Max(res, Dfs(r1, c1 + 1, r2 + 1)); + res = Math.Max(res, Dfs(r1, c1 + 1, r2)); + + res += grid[r1][c1]; + if (!(r1 == r2 && c1 == c2)) res += grid[r2][c2]; + + dp[r1, c1, r2] = res; + return res; + } +} +``` + +::tabs-end + +### Time & Space Complexity + +* Time complexity: $O(n ^ 3)$ +* Space complexity: $O(n ^ 3)$ + +--- + +## 4. Dynamic Programming (Bottom-Up) + +::tabs-start + +```python +class Solution: + def cherryPickup(self, grid: List[List[int]]) -> int: + n = len(grid) + dp = [[[float("-inf")] * n for _ in range(n)] for _ in range(n)] + + for r1 in reversed(range(n)): + for c1 in reversed(range(n)): + for r2 in reversed(range(n)): + c2 = r1 + c1 - r2 + if c2 < 0 or c2 >= n: + continue + if grid[r1][c1] == -1 or grid[r2][c2] == -1: + continue + + if r1 == n - 1 and c1 == n - 1: + dp[r1][c1][r2] = grid[r1][c1] + else: + res = max( + dp[r1 + 1][c1][r2 + 1] if r1 + 1 < n and r2 + 1 < n else -1000, + dp[r1 + 1][c1][r2] if r1 + 1 < n else -1000, + dp[r1][c1 + 1][r2 + 1] if c1 + 1 < n and r2 + 1 < n else -1000, + dp[r1][c1 + 1][r2] if c1 + 1 < n else -1000 + ) + if res == -1000: + continue + res += grid[r1][c1] + if (r1, c1) != (r2, c2): + res += grid[r2][c2] + dp[r1][c1][r2] = res + + return max(0, dp[0][0][0]) +``` + +```java +public class Solution { + public int cherryPickup(int[][] grid) { + int n = grid.length; + int[][][] dp = new int[n][n][n]; + for (int i = 0; i < n; i++) + for (int j = 0; j < n; j++) + for (int k = 0; k < n; k++) + dp[i][j][k] = Integer.MIN_VALUE / 2; + + for (int r1 = n - 1; r1 >= 0; r1--) { + for (int c1 = n - 1; c1 >= 0; c1--) { + for (int r2 = n - 1; r2 >= 0; r2--) { + int c2 = r1 + c1 - r2; + if (c2 < 0 || c2 >= n) continue; + if (grid[r1][c1] == -1 || grid[r2][c2] == -1) continue; + + if (r1 == n - 1 && c1 == n - 1) { + dp[r1][c1][r2] = grid[r1][c1]; + } else { + int res = Integer.MIN_VALUE / 2; + if (r1 + 1 < n && r2 + 1 < n) res = Math.max(res, dp[r1 + 1][c1][r2 + 1]); + if (r1 + 1 < n) res = Math.max(res, dp[r1 + 1][c1][r2]); + if (c1 + 1 < n && r2 + 1 < n) res = Math.max(res, dp[r1][c1 + 1][r2 + 1]); + if (c1 + 1 < n) res = Math.max(res, dp[r1][c1 + 1][r2]); + if (res == Integer.MIN_VALUE / 2) continue; + res += grid[r1][c1]; + if (r1 != r2 || c1 != c2) res += grid[r2][c2]; + dp[r1][c1][r2] = res; + } + } + } + } + return Math.max(0, dp[0][0][0]); + } +} +``` + +```cpp +class Solution { +public: + int cherryPickup(vector>& grid) { + int n = grid.size(); + vector>> dp(n, vector>(n, vector(n, -1000000000))); + + for (int r1 = n - 1; r1 >= 0; r1--) { + for (int c1 = n - 1; c1 >= 0; c1--) { + for (int r2 = n - 1; r2 >= 0; r2--) { + int c2 = r1 + c1 - r2; + if (c2 < 0 || c2 >= n) continue; + if (grid[r1][c1] == -1 || grid[r2][c2] == -1) continue; + + if (r1 == n - 1 && c1 == n - 1) { + dp[r1][c1][r2] = grid[r1][c1]; + } else { + int res = -1000000000; + if (r1 + 1 < n && r2 + 1 < n) res = max(res, dp[r1 + 1][c1][r2 + 1]); + if (r1 + 1 < n) res = max(res, dp[r1 + 1][c1][r2]); + if (c1 + 1 < n && r2 + 1 < n) res = max(res, dp[r1][c1 + 1][r2 + 1]); + if (c1 + 1 < n) res = max(res, dp[r1][c1 + 1][r2]); + if (res == -1000000000) continue; + res += grid[r1][c1]; + if (r1 != r2 || c1 != c2) res += grid[r2][c2]; + dp[r1][c1][r2] = res; + } + } + } + } + return max(0, dp[0][0][0]); + } +}; +``` + +```javascript +class Solution { + /** + * @param {number[][]} grid + * @return {number} + */ + cherryPickup(grid) { + const n = grid.length; + const dp = Array.from({ length: n }, () => + Array.from({ length: n }, () => Array(n).fill(-1e9)) + ); + + for (let r1 = n - 1; r1 >= 0; r1--) { + for (let c1 = n - 1; c1 >= 0; c1--) { + for (let r2 = n - 1; r2 >= 0; r2--) { + let c2 = r1 + c1 - r2; + if (c2 < 0 || c2 >= n) continue; + if (grid[r1][c1] === -1 || grid[r2][c2] === -1) continue; + + if (r1 === n - 1 && c1 === n - 1) { + dp[r1][c1][r2] = grid[r1][c1]; + } else { + let res = -1e9; + if (r1 + 1 < n && r2 + 1 < n) res = Math.max(res, dp[r1 + 1][c1][r2 + 1]); + if (r1 + 1 < n) res = Math.max(res, dp[r1 + 1][c1][r2]); + if (c1 + 1 < n && r2 + 1 < n) res = Math.max(res, dp[r1][c1 + 1][r2 + 1]); + if (c1 + 1 < n) res = Math.max(res, dp[r1][c1 + 1][r2]); + if (res === -1e9) continue; + res += grid[r1][c1]; + if (r1 !== r2 || c1 !== c2) res += grid[r2][c2]; + dp[r1][c1][r2] = res; + } + } + } + } + return Math.max(0, dp[0][0][0]); + } +} +``` + +```csharp +public class Solution { + public int CherryPickup(int[][] grid) { + int n = grid.Length; + int[,,] dp = new int[n,n,n]; + for (int i = 0; i < n; i++) + for (int j = 0; j < n; j++) + for (int k = 0; k < n; k++) + dp[i,j,k] = int.MinValue / 2; + + for (int r1 = n - 1; r1 >= 0; r1--) { + for (int c1 = n - 1; c1 >= 0; c1--) { + for (int r2 = n - 1; r2 >= 0; r2--) { + int c2 = r1 + c1 - r2; + if (c2 < 0 || c2 >= n) continue; + if (grid[r1][c1] == -1 || grid[r2][c2] == -1) continue; + + if (r1 == n - 1 && c1 == n - 1) { + dp[r1,c1,r2] = grid[r1][c1]; + } else { + int res = int.MinValue / 2; + if (r1 + 1 < n && r2 + 1 < n) res = Math.Max(res, dp[r1 + 1,c1,r2 + 1]); + if (r1 + 1 < n) res = Math.Max(res, dp[r1 + 1,c1,r2]); + if (c1 + 1 < n && r2 + 1 < n) res = Math.Max(res, dp[r1,c1 + 1,r2 + 1]); + if (c1 + 1 < n) res = Math.Max(res, dp[r1,c1 + 1,r2]); + if (res == int.MinValue / 2) continue; + res += grid[r1][c1]; + if (r1 != r2 || c1 != c2) res += grid[r2][c2]; + dp[r1,c1,r2] = res; + } + } + } + } + return Math.Max(0, dp[0,0,0]); + } +} +``` + +::tabs-end + +### Time & Space Complexity + +* Time complexity: $O(n ^ 3)$ +* Space complexity: $O(n ^ 3)$ + +--- + +## 5. Dynamic Programming (Space Optimized) + +::tabs-start + +```python +class Solution: + def cherryPickup(self, grid: List[List[int]]) -> int: + n = len(grid) + prev = [[float("-inf")] * n for _ in range(n)] + prev[0][0] = grid[0][0] + + for k in range(1, 2 * n - 1): + dp = [[float("-inf")] * n for _ in range(n)] + for r1 in range(max(0, k - (n - 1)), min(n, k + 1)): + c1 = k - r1 + if c1 >= n or grid[r1][c1] == -1: + continue + for r2 in range(max(0, k - (n - 1)), min(n, k + 1)): + c2 = k - r2 + if c2 >= n or grid[r2][c2] == -1: + continue + val = prev[r1][r2] + if r1 > 0: val = max(val, prev[r1 - 1][r2]) + if r2 > 0: val = max(val, prev[r1][r2 - 1]) + if r1 > 0 and r2 > 0: val = max(val, prev[r1 - 1][r2 - 1]) + if val < 0: continue + val += grid[r1][c1] + if r1 != r2: val += grid[r2][c2] + dp[r1][r2] = val + prev = dp + + return max(0, prev[n - 1][n - 1]) +``` + +```java +public class Solution { + public int cherryPickup(int[][] grid) { + int n = grid.length; + int[][] prev = new int[n][n]; + for (int[] row : prev) java.util.Arrays.fill(row, Integer.MIN_VALUE); + prev[0][0] = grid[0][0]; + + for (int k = 1; k < 2 * n - 1; k++) { + int[][] dp = new int[n][n]; + for (int[] row : dp) java.util.Arrays.fill(row, Integer.MIN_VALUE); + for (int r1 = Math.max(0, k - (n - 1)); r1 <= Math.min(n - 1, k); r1++) { + int c1 = k - r1; + if (c1 >= n || grid[r1][c1] == -1) continue; + for (int r2 = Math.max(0, k - (n - 1)); r2 <= Math.min(n - 1, k); r2++) { + int c2 = k - r2; + if (c2 >= n || grid[r2][c2] == -1) continue; + int val = prev[r1][r2]; + if (r1 > 0) val = Math.max(val, prev[r1 - 1][r2]); + if (r2 > 0) val = Math.max(val, prev[r1][r2 - 1]); + if (r1 > 0 && r2 > 0) val = Math.max(val, prev[r1 - 1][r2 - 1]); + if (val < 0) continue; + val += grid[r1][c1]; + if (r1 != r2) val += grid[r2][c2]; + dp[r1][r2] = val; + } + } + prev = dp; + } + + return Math.max(0, prev[n - 1][n - 1]); + } +} +``` + +```cpp +class Solution { +public: + int cherryPickup(vector>& grid) { + int n = grid.size(); + vector> prev(n, vector(n, INT_MIN)); + prev[0][0] = grid[0][0]; + + for (int k = 1; k < 2 * n - 1; k++) { + vector> dp(n, vector(n, INT_MIN)); + for (int r1 = max(0, k - (n - 1)); r1 <= min(n - 1, k); r1++) { + int c1 = k - r1; + if (c1 >= n || grid[r1][c1] == -1) continue; + for (int r2 = max(0, k - (n - 1)); r2 <= min(n - 1, k); r2++) { + int c2 = k - r2; + if (c2 >= n || grid[r2][c2] == -1) continue; + int val = prev[r1][r2]; + if (r1 > 0) val = max(val, prev[r1 - 1][r2]); + if (r2 > 0) val = max(val, prev[r1][r2 - 1]); + if (r1 > 0 && r2 > 0) val = max(val, prev[r1 - 1][r2 - 1]); + if (val < 0) continue; + val += grid[r1][c1]; + if (r1 != r2) val += grid[r2][c2]; + dp[r1][r2] = val; + } + } + prev = dp; + } + + return max(0, prev[n - 1][n - 1]); + } +}; +``` + +```javascript +class Solution { + /** + * @param {number[][]} grid + * @return {number} + */ + cherryPickup(grid) { + const n = grid.length; + let prev = Array.from({ length: n }, () => Array(n).fill(-Infinity)); + prev[0][0] = grid[0][0]; + + for (let k = 1; k < 2 * n - 1; k++) { + let dp = Array.from({ length: n }, () => Array(n).fill(-Infinity)); + for (let r1 = Math.max(0, k - (n - 1)); r1 <= Math.min(n - 1, k); r1++) { + let c1 = k - r1; + if (c1 >= n || grid[r1][c1] === -1) continue; + for (let r2 = Math.max(0, k - (n - 1)); r2 <= Math.min(n - 1, k); r2++) { + let c2 = k - r2; + if (c2 >= n || grid[r2][c2] === -1) continue; + let val = prev[r1][r2]; + if (r1 > 0) val = Math.max(val, prev[r1 - 1][r2]); + if (r2 > 0) val = Math.max(val, prev[r1][r2 - 1]); + if (r1 > 0 && r2 > 0) val = Math.max(val, prev[r1 - 1][r2 - 1]); + if (val < 0) continue; + val += grid[r1][c1]; + if (r1 !== r2) val += grid[r2][c2]; + dp[r1][r2] = val; + } + } + prev = dp; + } + + return Math.max(0, prev[n - 1][n - 1]); + } +} +``` + +```csharp +public class Solution { + public int CherryPickup(int[][] grid) { + int n = grid.Length; + int[][] prev = new int[n][]; + for (int i = 0; i < n; i++) { + prev[i] = new int[n]; + for (int j = 0; j < n; j++) prev[i][j] = int.MinValue; + } + prev[0][0] = grid[0][0]; + + for (int k = 1; k < 2 * n - 1; k++) { + int[][] dp = new int[n][]; + for (int i = 0; i < n; i++) { + dp[i] = new int[n]; + for (int j = 0; j < n; j++) dp[i][j] = int.MinValue; + } + for (int r1 = Math.Max(0, k - (n - 1)); r1 <= Math.Min(n - 1, k); r1++) { + int c1 = k - r1; + if (c1 >= n || grid[r1][c1] == -1) continue; + for (int r2 = Math.Max(0, k - (n - 1)); r2 <= Math.Min(n - 1, k); r2++) { + int c2 = k - r2; + if (c2 >= n || grid[r2][c2] == -1) continue; + int val = prev[r1][r2]; + if (r1 > 0) val = Math.Max(val, prev[r1 - 1][r2]); + if (r2 > 0) val = Math.Max(val, prev[r1][r2 - 1]); + if (r1 > 0 && r2 > 0) val = Math.Max(val, prev[r1 - 1][r2 - 1]); + if (val < 0) continue; + val += grid[r1][c1]; + if (r1 != r2) val += grid[r2][c2]; + dp[r1][r2] = val; + } + } + prev = dp; + } + + return Math.Max(0, prev[n - 1][n - 1]); + } +} +``` + +::tabs-end + +### Time & Space Complexity + +* Time complexity: $O(n ^ 3)$ +* Space complexity: $O(n ^ 2)$ \ No newline at end of file diff --git a/articles/longest-substring-with-at-most-two-distinct-characters.md b/articles/longest-substring-with-at-most-two-distinct-characters.md new file mode 100644 index 000000000..1968d0ae9 --- /dev/null +++ b/articles/longest-substring-with-at-most-two-distinct-characters.md @@ -0,0 +1,373 @@ +## 1. Brute Force + +::tabs-start + +```python +class Solution: + def lengthOfLongestSubstringTwoDistinct(self, s: str) -> int: + res, n = 0, len(s) + + for i in range(n): + seen = set() + cnt = curLen = 0 + for j in range(i, n): + seen.add(s[j]) + if len(seen) > 2: + break + curLen += 1 + res = max(res, curLen) + + return res +``` + +```java +public class Solution { + public int lengthOfLongestSubstringTwoDistinct(String s) { + int res = 0, n = s.length(); + + for (int i = 0; i < n; i++) { + Set seen = new HashSet<>(); + int curLen = 0; + for (int j = i; j < n; j++) { + seen.add(s.charAt(j)); + if (seen.size() > 2) { + break; + } + curLen++; + } + res = Math.max(res, curLen); + } + return res; + } +} +``` + +```cpp +class Solution { +public: + int lengthOfLongestSubstringTwoDistinct(string s) { + int res = 0, n = s.size(); + + for (int i = 0; i < n; i++) { + unordered_set seen; + int curLen = 0; + for (int j = i; j < n; j++) { + seen.insert(s[j]); + if (seen.size() > 2) { + break; + } + curLen++; + } + res = max(res, curLen); + } + return res; + } +}; +``` + +```javascript +class Solution { + /** + * @param {string} s + * @return {number} + */ + lengthOfLongestSubstringTwoDistinct(s) { + let res = 0, n = s.length; + + for (let i = 0; i < n; i++) { + let seen = new Set(); + let curLen = 0; + for (let j = i; j < n; j++) { + seen.add(s[j]); + if (seen.size > 2) { + break; + } + curLen++; + } + res = Math.max(res, curLen); + } + return res; + } +} +``` + +```csharp +public class Solution { + public int LengthOfLongestSubstringTwoDistinct(string s) { + int res = 0, n = s.Length; + + for (int i = 0; i < n; i++) { + HashSet seen = new HashSet(); + int curLen = 0; + for (int j = i; j < n; j++) { + seen.Add(s[j]); + if (seen.Count > 2) { + break; + } + curLen++; + } + res = Math.Max(res, curLen); + } + return res; + } +} +``` + +::tabs-end + +### Time & Space Complexity + +* Time complexity: $O(n ^ 2)$ +* Space complexity: $O(1)$ since we have at most $52$ different characters. + +--- + +## 2. Sliding Window + +::tabs-start + +```python +class Solution: + def lengthOfLongestSubstringTwoDistinct(self, s: str) -> int: + res, n = 0, len(s) + seen = defaultdict(int) + j = 0 + + for i in range(n): + seen[s[i]] += 1 + while len(seen) > 2: + seen[s[j]] -= 1 + if seen[s[j]] == 0: + seen.pop(s[j]) + j += 1 + res = max(res, i - j + 1) + return res +``` + +```java +public class Solution { + public int lengthOfLongestSubstringTwoDistinct(String s) { + int res = 0, n = s.length(); + Map seen = new HashMap<>(); + int j = 0; + + for (int i = 0; i < n; i++) { + seen.put(s.charAt(i), seen.getOrDefault(s.charAt(i), 0) + 1); + + while (seen.size() > 2) { + char c = s.charAt(j); + seen.put(c, seen.get(c) - 1); + if (seen.get(c) == 0) { + seen.remove(c); + } + j++; + } + res = Math.max(res, i - j + 1); + } + return res; + } +} +``` + +```cpp +class Solution { +public: + int lengthOfLongestSubstringTwoDistinct(string s) { + int res = 0, n = s.size(); + unordered_map seen; + int j = 0; + + for (int i = 0; i < n; i++) { + seen[s[i]]++; + + while (seen.size() > 2) { + char c = s[j]; + seen[c]--; + if (seen[c] == 0) { + seen.erase(c); + } + j++; + } + res = max(res, i - j + 1); + } + return res; + } +}; +``` + +```javascript +class Solution { + /** + * @param {string} s + * @return {number} + */ + lengthOfLongestSubstringTwoDistinct(s) { + let res = 0, n = s.length; + let seen = new Map(); + let j = 0; + + for (let i = 0; i < n; i++) { + seen.set(s[i], (seen.get(s[i]) || 0) + 1); + + while (seen.size > 2) { + let c = s[j]; + seen.set(c, seen.get(c) - 1); + if (seen.get(c) === 0) { + seen.delete(c); + } + j++; + } + res = Math.max(res, i - j + 1); + } + return res; + } +} +``` + +```csharp +public class Solution { + public int LengthOfLongestSubstringTwoDistinct(string s) { + int res = 0, n = s.Length; + Dictionary seen = new Dictionary(); + int j = 0; + + for (int i = 0; i < n; i++) { + if (!seen.ContainsKey(s[i])) { + seen[s[i]] = 0; + } + seen[s[i]]++; + + while (seen.Count > 2) { + char c = s[j]; + seen[c]--; + if (seen[c] == 0) { + seen.Remove(c); + } + j++; + } + res = Math.Max(res, i - j + 1); + } + return res; + } +} +``` + +::tabs-end + +### Time & Space Complexity + +* Time complexity: $O(n)$ +* Space complexity: $O(1)$ since we have at most $52$ different characters. + +--- + +## 3. Sliding Window (Optimal) + +::tabs-start + +```python +class Solution: + def lengthOfLongestSubstringTwoDistinct(self, s: str) -> int: + n = len(s) + count = defaultdict(int) + j = 0 + + for i in range(n): + count[s[i]] += 1 + if len(count) > 2: + count[s[j]] -= 1 + if count[s[j]] == 0: + count.pop(s[j]) + j += 1 + return i - j + 1 +``` + +```java +public class Solution { + public int lengthOfLongestSubstringTwoDistinct(String s) { + int n = s.length(); + Map count = new HashMap<>(); + int j = 0, i = 0; + for (i = 0; i < n; i++) { + count.put(s.charAt(i), count.getOrDefault(s.charAt(i), 0) + 1); + if (count.size() > 2) { + char c = s.charAt(j); + count.put(c, count.get(c) - 1); + if (count.get(c) == 0) count.remove(c); + j++; + } + } + return i - j; + } +} +``` + +```cpp +class Solution { +public: + int lengthOfLongestSubstringTwoDistinct(string s) { + int n = s.size(); + unordered_map count; + int j = 0, i = 0; + for (i = 0; i < n; i++) { + count[s[i]]++; + if (count.size() > 2) { + count[s[j]]--; + if (count[s[j]] == 0) count.erase(s[j]); + j++; + } + } + return i - j; + } +}; +``` + +```javascript +class Solution { + /** + * @param {string} s + * @return {number} + */ + lengthOfLongestSubstringTwoDistinct(s) { + let n = s.length; + let count = new Map(); + let j = 0, i = 0; + for (i = 0; i < n; i++) { + count.set(s[i], (count.get(s[i]) || 0) + 1); + if (count.size > 2) { + count.set(s[j], count.get(s[j]) - 1); + if (count.get(s[j]) === 0) count.delete(s[j]); + j++; + } + } + return i - j; + } +} +``` + +```csharp +public class Solution { + public int LengthOfLongestSubstringTwoDistinct(string s) { + int n = s.Length; + Dictionary count = new Dictionary(); + int j = 0, i = 0; + for (i = 0; i < n; i++) { + if (!count.ContainsKey(s[i])) count[s[i]] = 0; + count[s[i]]++; + if (count.Count > 2) { + count[s[j]]--; + if (count[s[j]] == 0) count.Remove(s[j]); + j++; + } + } + return i - j; + } +} +``` + +::tabs-end + +### Time & Space Complexity + +* Time complexity: $O(n)$ +* Space complexity: $O(1)$ since we have at most $52$ different characters. \ No newline at end of file diff --git a/articles/subarrays-with-k-different-integers.md b/articles/subarrays-with-k-different-integers.md index a61fba032..5f4d122f8 100644 --- a/articles/subarrays-with-k-different-integers.md +++ b/articles/subarrays-with-k-different-integers.md @@ -96,6 +96,30 @@ class Solution { } ``` +```csharp +public class Solution { + public int SubarraysWithKDistinct(int[] nums, int k) { + int n = nums.Length; + int res = 0; + + for (int i = 0; i < n; i++) { + HashSet seen = new HashSet(); + for (int j = i; j < n; j++) { + seen.Add(nums[j]); + if (seen.Count > k) { + break; + } + if (seen.Count == k) { + res++; + } + } + } + + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -239,6 +263,42 @@ class Solution { } ``` +```csharp +public class Solution { + public int SubarraysWithKDistinct(int[] nums, int k) { + return AtMostK(nums, k) - AtMostK(nums, k - 1); + } + + private int AtMostK(int[] nums, int k) { + Dictionary count = new Dictionary(); + int res = 0, l = 0; + + for (int r = 0; r < nums.Length; r++) { + if (!count.ContainsKey(nums[r])) { + count[nums[r]] = 0; + } + count[nums[r]]++; + if (count[nums[r]] == 1) { + k--; + } + + while (k < 0) { + count[nums[l]]--; + if (count[nums[l]] == 0) { + count.Remove(nums[l]); + k++; + } + l++; + } + + res += (r - l + 1); + } + + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -386,6 +446,42 @@ class Solution { } ``` +```csharp +public class Solution { + public int SubarraysWithKDistinct(int[] nums, int k) { + Dictionary count = new Dictionary(); + int res = 0, l_far = 0, l_near = 0; + + for (int r = 0; r < nums.Length; r++) { + if (!count.ContainsKey(nums[r])) { + count[nums[r]] = 0; + } + count[nums[r]]++; + + while (count.Count > k) { + count[nums[l_near]]--; + if (count[nums[l_near]] == 0) { + count.Remove(nums[l_near]); + } + l_near++; + l_far = l_near; + } + + while (count[nums[l_near]] > 1) { + count[nums[l_near]]--; + l_near++; + } + + if (count.Count == k) { + res += l_near - l_far + 1; + } + } + + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -544,6 +640,41 @@ class Solution { } ``` +```csharp +public class Solution { + public int SubarraysWithKDistinct(int[] nums, int k) { + int n = nums.Length; + int[] count = new int[n + 1]; + int res = 0, l = 0, cnt = 0; + + for (int r = 0; r < n; r++) { + count[nums[r]]++; + if (count[nums[r]] == 1) { + k--; + } + + if (k < 0) { + count[nums[l]]--; + l++; + k++; + cnt = 0; + } + + if (k == 0) { + while (count[nums[l]] > 1) { + count[nums[l]]--; + l++; + cnt++; + } + res += (cnt + 1); + } + } + + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity From c1c9a7241e8553e967ae9296cb0eb8e30c452c82 Mon Sep 17 00:00:00 2001 From: Sri Hari Date: Sat, 20 Sep 2025 10:05:12 +0530 Subject: [PATCH 3/9] Added articles, resolve git-issues --- articles/intersection-of-two-arrays.md | 115 +++++++++++ articles/largest-number.md | 46 +++++ ...lating-next-right-pointers-in-each-node.md | 194 +++++++++++++++++- articles/restore-ip-addresses.md | 66 ++++++ articles/single-element-in-a-sorted-array.md | 96 +++++++++ articles/spiral-matrix-ii.md | 106 ++++++++++ ...st-repeating-substring-with-replacement.md | 2 +- 7 files changed, 620 insertions(+), 5 deletions(-) diff --git a/articles/intersection-of-two-arrays.md b/articles/intersection-of-two-arrays.md index 33326dadb..022989700 100644 --- a/articles/intersection-of-two-arrays.md +++ b/articles/intersection-of-two-arrays.md @@ -76,6 +76,23 @@ class Solution { } ``` +```csharp +public class Solution { + public int[] Intersection(int[] nums1, int[] nums2) { + HashSet res = new HashSet(); + foreach (int i in nums1) { + foreach (int j in nums2) { + if (i == j) { + res.Add(i); + break; + } + } + } + return res.ToArray(); + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -207,6 +224,36 @@ class Solution { } ``` +```csharp +public class Solution { + public int[] Intersection(int[] nums1, int[] nums2) { + Array.Sort(nums1); + Array.Sort(nums2); + + int n = nums1.Length, m = nums2.Length; + List res = new List(); + int i = 0, j = 0; + + while (i < n && j < m) { + while (j < m && nums2[j] < nums1[i]) { + j++; + } + if (j < m) { + if (nums1[i] == nums2[j]) { + res.Add(nums1[i]); + } + i++; + while (i < n && nums1[i] == nums1[i - 1]) { + i++; + } + } + } + + return res.ToArray(); + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -300,6 +347,24 @@ class Solution { } ``` +```csharp +public class Solution { + public int[] Intersection(int[] nums1, int[] nums2) { + HashSet set1 = new HashSet(nums1); + HashSet set2 = new HashSet(nums2); + List res = new List(); + + foreach (int num in set1) { + if (set2.Contains(num)) { + res.Add(num); + } + } + + return res.ToArray(); + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -397,6 +462,27 @@ class Solution { } ``` +```csharp +public class Solution { + public int[] Intersection(int[] nums1, int[] nums2) { + Dictionary seen = new Dictionary(); + foreach (int num in nums1) { + seen[num] = 1; + } + + List res = new List(); + foreach (int num in nums2) { + if (seen.ContainsKey(num) && seen[num] == 1) { + seen[num] = 0; + res.Add(num); + } + } + + return res.ToArray(); + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -486,6 +572,24 @@ class Solution { } ``` +```csharp +public class Solution { + public int[] Intersection(int[] nums1, int[] nums2) { + HashSet seen = new HashSet(nums1); + List res = new List(); + + foreach (int num in nums2) { + if (seen.Contains(num)) { + res.Add(num); + seen.Remove(num); + } + } + + return res.ToArray(); + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -557,6 +661,17 @@ class Solution { } ``` +```csharp +public class Solution { + public int[] Intersection(int[] nums1, int[] nums2) { + HashSet set1 = new HashSet(nums1); + HashSet set2 = new HashSet(nums2); + set1.IntersectWith(set2); + return set1.ToArray(); + } +} +``` + ::tabs-end ### Time & Space Complexity diff --git a/articles/largest-number.md b/articles/largest-number.md index cb16f81db..d7780c2c8 100644 --- a/articles/largest-number.md +++ b/articles/largest-number.md @@ -99,6 +99,32 @@ class Solution { } ``` +```csharp +public class Solution { + public string LargestNumber(int[] nums) { + List arr = new List(); + foreach (int num in nums) { + arr.Add(num.ToString()); + } + + List res = new List(); + while (arr.Count > 0) { + int maxi = 0; + for (int i = 1; i < arr.Count; i++) { + if (string.Compare(arr[i] + arr[maxi], arr[maxi] + arr[i]) > 0) { + maxi = i; + } + } + res.Add(arr[maxi]); + arr.RemoveAt(maxi); + } + + string result = string.Join("", res); + return result[0] == '0' ? "0" : result; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -178,6 +204,26 @@ class Solution { } ``` +```csharp +public class Solution { + public string LargestNumber(int[] nums) { + string[] arr = new string[nums.Length]; + for (int i = 0; i < nums.Length; i++) { + arr[i] = nums[i].ToString(); + } + + Array.Sort(arr, (a, b) => { + string order1 = a + b; + string order2 = b + a; + return order2.CompareTo(order1); + }); + + string result = string.Join("", arr); + return result[0] == '0' ? "0" : result; + } +} +``` + ::tabs-end ### Time & Space Complexity diff --git a/articles/populating-next-right-pointers-in-each-node.md b/articles/populating-next-right-pointers-in-each-node.md index facd98067..29b601a20 100644 --- a/articles/populating-next-right-pointers-in-each-node.md +++ b/articles/populating-next-right-pointers-in-each-node.md @@ -140,7 +140,7 @@ public: ```javascript /** * Definition for a binary tree node. - * class TreeNode { + * class Node { * constructor(val = 0, left = null, right = null, next = null) { * this.val = val; * this.left = left; @@ -183,6 +183,55 @@ class Solution { } ``` +```csharp +/* +// Definition for a Node. +public class Node { + public int val; + public Node left; + public Node right; + public Node next; + + public Node() {} + + public Node(int _val) { + val = _val; + } + + public Node(int _val, Node _left, Node _right, Node _next) { + val = _val; + left = _left; + right = _right; + next = _next; + } +} +*/ + +public class Solution { + public Node Connect(Node root) { + if (root == null) return null; + + Queue q = new Queue(); + q.Enqueue(root); + + while (q.Count > 0) { + int levelSize = q.Count; + while (levelSize > 0) { + Node node = q.Dequeue(); + if (levelSize > 1) { + node.next = q.Peek(); + } + if (node.left != null) q.Enqueue(node.left); + if (node.right != null) q.Enqueue(node.right); + levelSize--; + } + } + + return root; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -322,7 +371,7 @@ private: ```javascript /** * Definition for a binary tree node. - * class TreeNode { + * class Node { * constructor(val = 0, left = null, right = null, next = null) { * this.val = val; * this.left = left; @@ -360,6 +409,54 @@ class Solution { } ``` +```csharp +/* +// Definition for a Node. +public class Node { + public int val; + public Node left; + public Node right; + public Node next; + + public Node() {} + + public Node(int _val) { + val = _val; + } + + public Node(int _val, Node _left, Node _right, Node _next) { + val = _val; + left = _left; + right = _right; + next = _next; + } +} +*/ + +public class Solution { + public Node Connect(Node root) { + Dictionary mp = new Dictionary(); + + void Dfs(Node node, int depth) { + if (node == null) return; + + if (!mp.ContainsKey(depth)) { + mp[depth] = node; + } else { + mp[depth].next = node; + mp[depth] = node; + } + + Dfs(node.left, depth + 1); + Dfs(node.right, depth + 1); + } + + Dfs(root, 0); + return root; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -485,7 +582,7 @@ public: ```javascript /** * Definition for a binary tree node. - * class TreeNode { + * class Node { * constructor(val = 0, left = null, right = null, next = null) { * this.val = val; * this.left = left; @@ -518,6 +615,48 @@ class Solution { } ``` +```csharp +/* +// Definition for a Node. +public class Node { + public int val; + public Node left; + public Node right; + public Node next; + + public Node() {} + + public Node(int _val) { + val = _val; + } + + public Node(int _val, Node _left, Node _right, Node _next) { + val = _val; + left = _left; + right = _right; + next = _next; + } +} +*/ + +public class Solution { + public Node Connect(Node root) { + if (root == null) return root; + + if (root.left != null) { + root.left.next = root.right; + if (root.next != null) { + root.right.next = root.next.left; + } + Connect(root.left); + Connect(root.right); + } + + return root; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -654,7 +793,7 @@ public: ```javascript /** * Definition for a binary tree node. - * class TreeNode { + * class Node { * constructor(val = 0, left = null, right = null, next = null) { * this.val = val; * this.left = left; @@ -693,6 +832,53 @@ class Solution { } ``` +```csharp +/* +// Definition for a Node. +public class Node { + public int val; + public Node left; + public Node right; + public Node next; + + public Node() {} + + public Node(int _val) { + val = _val; + } + + public Node(int _val, Node _left, Node _right, Node _next) { + val = _val; + left = _left; + right = _right; + next = _next; + } +} +*/ + +public class Solution { + public Node Connect(Node root) { + Node cur = root; + Node nxt = root != null ? root.left : null; + + while (cur != null && nxt != null) { + cur.left.next = cur.right; + if (cur.next != null) { + cur.right.next = cur.next.left; + } + + cur = cur.next; + if (cur == null) { + cur = nxt; + nxt = cur.left; + } + } + + return root; + } +} +``` + ::tabs-end ### Time & Space Complexity diff --git a/articles/restore-ip-addresses.md b/articles/restore-ip-addresses.md index 2c00656c9..ac537db54 100644 --- a/articles/restore-ip-addresses.md +++ b/articles/restore-ip-addresses.md @@ -113,6 +113,34 @@ class Solution { } ``` +```csharp +public class Solution { + public List RestoreIpAddresses(string s) { + List res = new List(); + if (s.Length > 12) return res; + + void Backtrack(int i, int dots, string curIP) { + if (dots == 4 && i == s.Length) { + res.Add(curIP.Substring(0, curIP.Length - 1)); + return; + } + if (dots > 4) return; + + for (int j = i; j < Math.Min(i + 3, s.Length); j++) { + if (i != j && s[i] == '0') continue; + string part = s.Substring(i, j - i + 1); + if (int.Parse(part) < 256) { + Backtrack(j + 1, dots + 1, curIP + part + "."); + } + } + } + + Backtrack(0, 0, ""); + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -276,6 +304,44 @@ class Solution { } ``` +```csharp +public class Solution { + public List RestoreIpAddresses(string s) { + List res = new List(); + if (s.Length > 12) return res; + + bool Valid(string num) { + return num.Length == 1 || (int.Parse(num) < 256 && num[0] != '0'); + } + + void Add(int s1, int s2, int s3, int s4) { + if (s1 + s2 + s3 + s4 != s.Length) return; + + string num1 = s.Substring(0, s1); + string num2 = s.Substring(s1, s2); + string num3 = s.Substring(s1 + s2, s3); + string num4 = s.Substring(s1 + s2 + s3); + + if (Valid(num1) && Valid(num2) && Valid(num3) && Valid(num4)) { + res.Add(num1 + "." + num2 + "." + num3 + "." + num4); + } + } + + for (int seg1 = 1; seg1 < 4; seg1++) { + for (int seg2 = 1; seg2 < 4; seg2++) { + for (int seg3 = 1; seg3 < 4; seg3++) { + for (int seg4 = 1; seg4 < 4; seg4++) { + Add(seg1, seg2, seg3, seg4); + } + } + } + } + + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity diff --git a/articles/single-element-in-a-sorted-array.md b/articles/single-element-in-a-sorted-array.md index 8855fac24..98db97252 100644 --- a/articles/single-element-in-a-sorted-array.md +++ b/articles/single-element-in-a-sorted-array.md @@ -69,6 +69,22 @@ class Solution { } ``` +```csharp +public class Solution { + public int SingleNonDuplicate(int[] nums) { + int n = nums.Length; + for (int i = 0; i < n; i++) { + if ((i > 0 && nums[i] == nums[i - 1]) || + (i < n - 1 && nums[i] == nums[i + 1])) { + continue; + } + return nums[i]; + } + return -1; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -132,6 +148,18 @@ class Solution { } ``` +```csharp +public class Solution { + public int SingleNonDuplicate(int[] nums) { + int xorr = 0; + foreach (int num in nums) { + xorr ^= num; + } + return xorr; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -244,6 +272,33 @@ class Solution { } ``` +```csharp +public class Solution { + public int SingleNonDuplicate(int[] nums) { + int l = 0, r = nums.Length - 1; + + while (l <= r) { + int m = l + (r - l) / 2; + + if ((m - 1 < 0 || nums[m - 1] != nums[m]) && + (m + 1 == nums.Length || nums[m] != nums[m + 1])) { + return nums[m]; + } + + int leftSize = (m - 1 >= 0 && nums[m - 1] == nums[m]) ? m - 1 : m; + + if (leftSize % 2 == 1) { + r = m - 1; + } else { + l = m + 1; + } + } + + return -1; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -346,6 +401,28 @@ class Solution { } ``` +```csharp +public class Solution { + public int SingleNonDuplicate(int[] nums) { + int l = 0, r = nums.Length - 1; + + while (l < r) { + int m = l + (r - l) / 2; + if ((m & 1) == 1) { + m--; + } + if (nums[m] != nums[m + 1]) { + r = m; + } else { + l = m + 2; + } + } + + return nums[l]; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -437,6 +514,25 @@ class Solution { } ``` +```csharp +public class Solution { + public int SingleNonDuplicate(int[] nums) { + int l = 0, r = nums.Length - 1; + + while (l < r) { + int m = (l + r) >> 1; + if (nums[m] != nums[m ^ 1]) { + r = m; + } else { + l = m + 1; + } + } + + return nums[l]; + } +} +``` + ::tabs-end ### Time & Space Complexity diff --git a/articles/spiral-matrix-ii.md b/articles/spiral-matrix-ii.md index 2c066c72b..e3d1fd7f0 100644 --- a/articles/spiral-matrix-ii.md +++ b/articles/spiral-matrix-ii.md @@ -158,6 +158,46 @@ class Solution { } ``` +```csharp +public class Solution { + public int[][] GenerateMatrix(int n) { + int[][] mat = new int[n][]; + for (int i = 0; i < n; i++) mat[i] = new int[n]; + int left = 0, right = n - 1; + int top = 0, bottom = n - 1; + int val = 1; + + while (left <= right) { + for (int c = left; c <= right; c++) { + mat[top][c] = val; + val++; + } + top++; + + for (int r = top; r <= bottom; r++) { + mat[r][right] = val; + val++; + } + right--; + + for (int c = right; c >= left; c--) { + mat[bottom][c] = val; + val++; + } + bottom--; + + for (int r = bottom; r >= top; r--) { + mat[r][left] = val; + val++; + } + left++; + } + + return mat; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -341,6 +381,48 @@ class Solution { } ``` +```csharp +public class Solution { + public int[][] GenerateMatrix(int n) { + int[][] mat = new int[n][]; + for (int i = 0; i < n; i++) mat[i] = new int[n]; + + void Fill(int left, int right, int top, int bottom, int val) { + if (left > right || top > bottom) return; + + for (int c = left; c <= right; c++) { + mat[top][c] = val; + val++; + } + top++; + + for (int r = top; r <= bottom; r++) { + mat[r][right] = val; + val++; + } + right--; + + for (int c = right; c >= left; c--) { + mat[bottom][c] = val; + val++; + } + bottom--; + + for (int r = bottom; r >= top; r--) { + mat[r][left] = val; + val++; + } + left++; + + Fill(left, right, top, bottom, val); + } + + Fill(0, n - 1, 0, n - 1, 1); + return mat; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -454,6 +536,30 @@ class Solution { } ``` +```csharp +public class Solution { + public int[][] GenerateMatrix(int n) { + int[][] mat = new int[n][]; + for (int i = 0; i < n; i++) mat[i] = new int[n]; + int r = 0, c = 0; + int dr = 0, dc = 1; + + for (int val = 0; val < n * n; val++) { + mat[r][c] = val + 1; + if (mat[(r + dr + n) % n][(c + dc + n) % n] != 0) { + int temp = dr; + dr = dc; + dc = -temp; + } + r += dr; + c += dc; + } + + return mat; + } +} +``` + ::tabs-end ### Time & Space Complexity diff --git a/hints/longest-repeating-substring-with-replacement.md b/hints/longest-repeating-substring-with-replacement.md index 7cd03766b..0dbae5ad2 100644 --- a/hints/longest-repeating-substring-with-replacement.md +++ b/hints/longest-repeating-substring-with-replacement.md @@ -10,7 +10,7 @@
Hint 1

- Which characters would you replace in a string to make all its characters unique? Can you think with respect to the frequency of the characters? + Which characters would you replace in a string to make all its characters identical? Can you think with respect to the frequency of the characters?

From 20cf8901e216d1b6b25e38298a59ca13ecc32d35 Mon Sep 17 00:00:00 2001 From: Sri Hari Date: Tue, 23 Sep 2025 21:23:57 +0530 Subject: [PATCH 4/9] Added articles --- .../check-completeness-of-a-binary-tree.md | 147 ++++++++++++++++ articles/continuous-subarray-sum.md | 39 +++++ articles/merge-two-binary-trees.md | 163 ++++++++++++++++++ 3 files changed, 349 insertions(+) diff --git a/articles/check-completeness-of-a-binary-tree.md b/articles/check-completeness-of-a-binary-tree.md index 86acd8fd4..e8069ef71 100644 --- a/articles/check-completeness-of-a-binary-tree.md +++ b/articles/check-completeness-of-a-binary-tree.md @@ -138,6 +138,44 @@ class Solution { } ``` +```csharp +/** + * Definition for a binary tree node. + * public class TreeNode { + * public int val; + * public TreeNode left; + * public TreeNode right; + * public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +public class Solution { + public bool IsCompleteTree(TreeNode root) { + Queue q = new Queue(); + q.Enqueue(root); + + while (q.Count > 0) { + TreeNode node = q.Dequeue(); + if (node != null) { + q.Enqueue(node.left); + q.Enqueue(node.right); + } else { + while (q.Count > 0) { + if (q.Dequeue() != null) { + return false; + } + } + } + } + + return true; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -281,6 +319,44 @@ class Solution { } ``` +```csharp +/** + * Definition for a binary tree node. + * public class TreeNode { + * public int val; + * public TreeNode left; + * public TreeNode right; + * public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +public class Solution { + public bool IsCompleteTree(TreeNode root) { + Queue q = new Queue(); + q.Enqueue(root); + bool nullSeen = false; + + while (q.Count > 0) { + TreeNode node = q.Dequeue(); + if (node != null) { + if (nullSeen) { + return false; + } + q.Enqueue(node.left); + q.Enqueue(node.right); + } else { + nullSeen = true; + } + } + + return true; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -426,6 +502,39 @@ class Solution { } ``` +```csharp +/** + * Definition for a binary tree node. + * public class TreeNode { + * public int val; + * public TreeNode left; + * public TreeNode right; + * public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +public class Solution { + public bool IsCompleteTree(TreeNode root) { + int n = CountNodes(root); + return Dfs(root, 0, n); + } + + private bool Dfs(TreeNode node, int index, int n) { + if (node == null) return true; + if (index >= n) return false; + return Dfs(node.left, 2 * index + 1, n) && Dfs(node.right, 2 * index + 2, n); + } + + private int CountNodes(TreeNode node) { + if (node == null) return 0; + return 1 + CountNodes(node.left) + CountNodes(node.right); + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -586,6 +695,44 @@ class Solution { } ``` +```csharp +/** + * Definition for a binary tree node. + * public class TreeNode { + * public int val; + * public TreeNode left; + * public TreeNode right; + * public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +public class Solution { + private int treeHgt = 0; + private bool nullSeen = false; + + public bool IsCompleteTree(TreeNode root) { + return Dfs(root, 0); + } + + private bool Dfs(TreeNode node, int hgt) { + if (node == null) { + if (treeHgt == 0) { + treeHgt = hgt; + } else if (hgt == treeHgt - 1) { + nullSeen = true; + } else if (hgt != treeHgt) { + return false; + } + return !(hgt == treeHgt && nullSeen); + } + return Dfs(node.left, hgt + 1) && Dfs(node.right, hgt + 1); + } +} +``` + ::tabs-end ### Time & Space Complexity diff --git a/articles/continuous-subarray-sum.md b/articles/continuous-subarray-sum.md index a55bdad78..875fe91e5 100644 --- a/articles/continuous-subarray-sum.md +++ b/articles/continuous-subarray-sum.md @@ -65,6 +65,23 @@ class Solution { } ``` +```csharp +public class Solution { + public bool CheckSubarraySum(int[] nums, int k) { + for (int i = 0; i < nums.Length - 1; i++) { + int sum = nums[i]; + for (int j = i + 1; j < nums.Length; j++) { + sum += nums[j]; + if (sum % k == 0) { + return true; + } + } + } + return false; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -167,6 +184,28 @@ class Solution { } ``` +```csharp +public class Solution { + public bool CheckSubarraySum(int[] nums, int k) { + Dictionary remainder = new Dictionary(); + remainder[0] = -1; + int total = 0; + + for (int i = 0; i < nums.Length; i++) { + total += nums[i]; + int r = total % k; + if (!remainder.ContainsKey(r)) { + remainder[r] = i; + } else if (i - remainder[r] > 1) { + return true; + } + } + + return false; + } +} +``` + ::tabs-end ### Time & Space Complexity diff --git a/articles/merge-two-binary-trees.md b/articles/merge-two-binary-trees.md index d0811dfb2..413d50634 100644 --- a/articles/merge-two-binary-trees.md +++ b/articles/merge-two-binary-trees.md @@ -133,6 +133,38 @@ class Solution { } ``` +```csharp +/** + * Definition for a binary tree node. + * public class TreeNode { + * public int val; + * public TreeNode left; + * public TreeNode right; + * public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +public class Solution { + public TreeNode MergeTrees(TreeNode root1, TreeNode root2) { + if (root1 == null && root2 == null) { + return null; + } + + int v1 = root1 != null ? root1.val : 0; + int v2 = root2 != null ? root2.val : 0; + TreeNode root = new TreeNode(v1 + v2); + + root.left = MergeTrees(root1 != null ? root1.left : null, root2 != null ? root2.left : null); + root.right = MergeTrees(root1 != null ? root1.right : null, root2 != null ? root2.right : null); + + return root; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -254,6 +286,37 @@ class Solution { } ``` +```csharp +/** + * Definition for a binary tree node. + * public class TreeNode { + * public int val; + * public TreeNode left; + * public TreeNode right; + * public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +public class Solution { + public TreeNode MergeTrees(TreeNode root1, TreeNode root2) { + if (root1 == null) { + return root2; + } + if (root2 == null) { + return root1; + } + + root1.val += root2.val; + root1.left = MergeTrees(root1.left, root2.left); + root1.right = MergeTrees(root1.right, root2.right); + return root1; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -457,6 +520,60 @@ class Solution { } ``` +```csharp +/** + * Definition for a binary tree node. + * public class TreeNode { + * public int val; + * public TreeNode left; + * public TreeNode right; + * public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +public class Solution { + public TreeNode MergeTrees(TreeNode root1, TreeNode root2) { + if (root1 == null) { + return root2; + } + if (root2 == null) { + return root1; + } + + TreeNode root = new TreeNode(root1.val + root2.val); + Stack<(TreeNode, TreeNode, TreeNode)> stack = new Stack<(TreeNode, TreeNode, TreeNode)>(); + stack.Push((root1, root2, root)); + + while (stack.Count > 0) { + var (node1, node2, node) = stack.Pop(); + + if (node1.left != null && node2.left != null) { + node.left = new TreeNode(node1.left.val + node2.left.val); + stack.Push((node1.left, node2.left, node.left)); + } else if (node1.left == null) { + node.left = node2.left; + } else { + node.left = node1.left; + } + + if (node1.right != null && node2.right != null) { + node.right = new TreeNode(node1.right.val + node2.right.val); + stack.Push((node1.right, node2.right, node.right)); + } else if (node1.right == null) { + node.right = node2.right; + } else { + node.right = node1.right; + } + } + + return root; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -655,6 +772,52 @@ class Solution { } ``` +```csharp +/** + * Definition for a binary tree node. + * public class TreeNode { + * public int val; + * public TreeNode left; + * public TreeNode right; + * public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +public class Solution { + public TreeNode MergeTrees(TreeNode root1, TreeNode root2) { + if (root1 == null) return root2; + if (root2 == null) return root1; + + Stack<(TreeNode, TreeNode)> stack = new Stack<(TreeNode, TreeNode)>(); + stack.Push((root1, root2)); + + while (stack.Count > 0) { + var (node1, node2) = stack.Pop(); + if (node1 == null || node2 == null) continue; + + node1.val += node2.val; + + if (node1.left != null && node2.left != null) { + stack.Push((node1.left, node2.left)); + } else if (node1.left == null) { + node1.left = node2.left; + } + + if (node1.right != null && node2.right != null) { + stack.Push((node1.right, node2.right)); + } else if (node1.right == null) { + node1.right = node2.right; + } + } + + return root1; + } +} +``` + ::tabs-end ### Time & Space Complexity From d3e2db69eed808475a508b0a440d1140fa286371 Mon Sep 17 00:00:00 2001 From: Sri Hari Date: Fri, 26 Sep 2025 23:23:37 +0530 Subject: [PATCH 5/9] Added articles --- articles/binary-search-tree-iterator.md | 169 ++++++++++++++++++ articles/find-pivot-index.md | 61 +++++++ ...ve-all-adjacent-duplicates-in-string-ii.md | 123 ++++++++++++- 3 files changed, 349 insertions(+), 4 deletions(-) diff --git a/articles/binary-search-tree-iterator.md b/articles/binary-search-tree-iterator.md index 4eccdb1ef..ecd2fa2c8 100644 --- a/articles/binary-search-tree-iterator.md +++ b/articles/binary-search-tree-iterator.md @@ -168,6 +168,49 @@ class BSTIterator { } ``` +```csharp +/** + * Definition for a binary tree node. + * public class TreeNode { + * public int val; + * public TreeNode left; + * public TreeNode right; + * public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +public class BSTIterator { + private List arr; + private int itr; + + public BSTIterator(TreeNode root) { + arr = new List(); + itr = 0; + Dfs(root); + } + + private void Dfs(TreeNode node) { + if (node == null) return; + Dfs(node.left); + arr.Add(node.val); + Dfs(node.right); + } + + public int Next() { + int val = arr[itr]; + itr++; + return val; + } + + public bool HasNext() { + return itr < arr.Count; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -350,6 +393,52 @@ class BSTIterator { } ``` +```csharp +/** + * Definition for a binary tree node. + * public class TreeNode { + * public int val; + * public TreeNode left; + * public TreeNode right; + * public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +public class BSTIterator { + private List arr; + private int itr; + + public BSTIterator(TreeNode root) { + arr = new List(); + itr = 0; + + Stack stack = new Stack(); + while (root != null || stack.Count > 0) { + while (root != null) { + stack.Push(root); + root = root.left; + } + root = stack.Pop(); + arr.Add(root.val); + root = root.right; + } + } + + public int Next() { + int val = arr[itr]; + itr++; + return val; + } + + public bool HasNext() { + return itr < arr.Count; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -522,6 +611,47 @@ class BSTIterator { } ``` +```csharp +/** + * Definition for a binary tree node. + * public class TreeNode { + * public int val; + * public TreeNode left; + * public TreeNode right; + * public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +public class BSTIterator { + private Stack stack; + + public BSTIterator(TreeNode root) { + stack = new Stack(); + while (root != null) { + stack.Push(root); + root = root.left; + } + } + + public int Next() { + TreeNode node = stack.Pop(); + TreeNode cur = node.right; + while (cur != null) { + stack.Push(cur); + cur = cur.left; + } + return node.val; + } + + public bool HasNext() { + return stack.Count > 0; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -689,6 +819,45 @@ class BSTIterator { } ``` +```csharp +/** + * Definition for a binary tree node. + * public class TreeNode { + * public int val; + * public TreeNode left; + * public TreeNode right; + * public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +public class BSTIterator { + private TreeNode cur; + private Stack stack; + + public BSTIterator(TreeNode root) { + cur = root; + stack = new Stack(); + } + + public int Next() { + while (cur != null) { + stack.Push(cur); + cur = cur.left; + } + TreeNode node = stack.Pop(); + cur = node.right; + return node.val; + } + + public bool HasNext() { + return cur != null || stack.Count > 0; + } +} +``` + ::tabs-end ### Time & Space Complexity diff --git a/articles/find-pivot-index.md b/articles/find-pivot-index.md index 0354d06e4..a96bd7ac7 100644 --- a/articles/find-pivot-index.md +++ b/articles/find-pivot-index.md @@ -86,6 +86,27 @@ class Solution { } ``` +```csharp +public class Solution { + public int PivotIndex(int[] nums) { + int n = nums.Length; + for (int i = 0; i < n; i++) { + int leftSum = 0, rightSum = 0; + for (int l = 0; l < i; l++) { + leftSum += nums[l]; + } + for (int r = i + 1; r < n; r++) { + rightSum += nums[r]; + } + if (leftSum == rightSum) { + return i; + } + } + return -1; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -183,6 +204,26 @@ class Solution { } ``` +```csharp +public class Solution { + public int PivotIndex(int[] nums) { + int n = nums.Length; + int[] prefixSum = new int[n + 1]; + for (int i = 0; i < n; i++) { + prefixSum[i + 1] = prefixSum[i] + nums[i]; + } + for (int i = 0; i < n; i++) { + int leftSum = prefixSum[i]; + int rightSum = prefixSum[n] - prefixSum[i + 1]; + if (leftSum == rightSum) { + return i; + } + } + return -1; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -277,6 +318,26 @@ class Solution { } ``` +```csharp +public class Solution { + public int PivotIndex(int[] nums) { + int total = 0; + foreach (int num in nums) { + total += num; + } + int leftSum = 0; + for (int i = 0; i < nums.Length; i++) { + int rightSum = total - nums[i] - leftSum; + if (leftSum == rightSum) { + return i; + } + leftSum += nums[i]; + } + return -1; + } +} +``` + ::tabs-end ### Time & Space Complexity diff --git a/articles/remove-all-adjacent-duplicates-in-string-ii.md b/articles/remove-all-adjacent-duplicates-in-string-ii.md index 3e6d60c3f..b39c88b1e 100644 --- a/articles/remove-all-adjacent-duplicates-in-string-ii.md +++ b/articles/remove-all-adjacent-duplicates-in-string-ii.md @@ -5,7 +5,7 @@ ```python class Solution: def removeDuplicates(self, s: str, k: int) -> str: - while True: + while s: flag = False cur = s[0] cnt = 1 @@ -28,7 +28,7 @@ class Solution: ```java public class Solution { public String removeDuplicates(String s, int k) { - while (true) { + while (s.length() != 0) { boolean flag = false; char cur = s.charAt(0); int cnt = 1; @@ -60,7 +60,7 @@ public class Solution { class Solution { public: string removeDuplicates(string s, int k) { - while (true) { + while (s.length()) { bool flag = false; char cur = s[0]; int cnt = 1; @@ -96,7 +96,7 @@ class Solution { * @return {string} */ removeDuplicates(s, k) { - while (true) { + while (s) { let flag = false; let cur = s[0]; let cnt = 1; @@ -124,6 +124,37 @@ class Solution { } ``` +```csharp +public class Solution { + public string RemoveDuplicates(string s, int k) { + while (s.Length != 0) { + bool flag = false; + char cur = s[0]; + int cnt = 1; + + for (int i = 1; i < s.Length; i++) { + if (cur != s[i]) { + cnt = 0; + cur = s[i]; + } + cnt++; + if (cnt == k) { + s = s.Substring(0, i - cnt + 1) + s.Substring(i + 1); + flag = true; + break; + } + } + + if (!flag) { + break; + } + } + + return s; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -245,6 +276,34 @@ class Solution { } ``` +```csharp +public class Solution { + public string RemoveDuplicates(string s, int k) { + var stack = new List(); + var chars = new List(s); + int n = chars.Count; + int i = 0; + + while (i < n) { + if (i == 0 || chars[i] != chars[i - 1]) { + stack.Add(1); + } else { + stack[stack.Count - 1]++; + if (stack[stack.Count - 1] == k) { + stack.RemoveAt(stack.Count - 1); + chars.RemoveRange(i - k + 1, k); + i -= k; + n -= k; + } + } + i++; + } + + return new string(chars.ToArray()); + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -359,6 +418,34 @@ class Solution { } ``` +```csharp +public class Solution { + public string RemoveDuplicates(string s, int k) { + var stack = new List<(char ch, int cnt)>(); + + foreach (char c in s) { + if (stack.Count > 0 && stack[stack.Count - 1].ch == c) { + var top = stack[stack.Count - 1]; + stack[stack.Count - 1] = (top.ch, top.cnt + 1); + } else { + stack.Add((c, 1)); + } + + if (stack[stack.Count - 1].cnt == k) { + stack.RemoveAt(stack.Count - 1); + } + } + + var sb = new System.Text.StringBuilder(); + foreach (var (ch, cnt) in stack) { + sb.Append(new string(ch, cnt)); + } + + return sb.ToString(); + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -459,6 +546,34 @@ class Solution { } ``` +```csharp +public class Solution { + public string RemoveDuplicates(string s, int k) { + int n = s.Length; + char[] arr = s.ToCharArray(); + int[] count = new int[n]; + int i = 0; + + for (int j = 0; j < n; j++) { + arr[i] = arr[j]; + count[i] = 1; + + if (i > 0 && arr[i - 1] == arr[j]) { + count[i] += count[i - 1]; + } + + if (count[i] == k) { + i -= k; + } + + i++; + } + + return new string(arr, 0, i); + } +} +``` + ::tabs-end ### Time & Space Complexity From 4125087e5b68b3527ff4340d04520ab8d644213e Mon Sep 17 00:00:00 2001 From: Sri Hari Date: Sat, 27 Sep 2025 21:18:39 +0530 Subject: [PATCH 6/9] Added articles --- ...inary-tree-zigzag-level-order-traversal.md | 188 ++++++++++++++++++ ...aximum-points-you-can-obtain-from-cards.md | 104 ++++++++++ articles/middle-of-the-linked-list.md | 82 ++++++++ articles/two-city-scheduling.md | 148 ++++++++++++++ 4 files changed, 522 insertions(+) diff --git a/articles/binary-tree-zigzag-level-order-traversal.md b/articles/binary-tree-zigzag-level-order-traversal.md index 449ee2151..ad247d20c 100644 --- a/articles/binary-tree-zigzag-level-order-traversal.md +++ b/articles/binary-tree-zigzag-level-order-traversal.md @@ -144,6 +144,49 @@ class Solution { } ``` +```csharp +/** + * Definition for a binary tree node. + * public class TreeNode { + * public int val; + * public TreeNode left; + * public TreeNode right; + * public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +public class Solution { + public List> ZigzagLevelOrder(TreeNode root) { + var res = new List>(); + if (root == null) return res; + + var q = new Queue(); + q.Enqueue(root); + + while (q.Count > 0) { + int size = q.Count; + var level = new List(); + + for (int i = 0; i < size; i++) { + var node = q.Dequeue(); + level.Add(node.val); + + if (node.left != null) q.Enqueue(node.left); + if (node.right != null) q.Enqueue(node.right); + } + + if (res.Count % 2 == 1) level.Reverse(); + res.Add(level); + } + + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -303,6 +346,46 @@ class Solution { } ``` +```csharp +/** + * Definition for a binary tree node. + * public class TreeNode { + * public int val; + * public TreeNode left; + * public TreeNode right; + * public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +public class Solution { + public List> ZigzagLevelOrder(TreeNode root) { + var res = new List>(); + if (root == null) return res; + + var q = new Queue(); + q.Enqueue(root); + + while (q.Count > 0) { + int size = q.Count; + var level = new int[size]; + for (int i = 0; i < size; i++) { + var node = q.Dequeue(); + int idx = (res.Count % 2 == 1) ? size - i - 1 : i; + level[idx] = node.val; + if (node.left != null) q.Enqueue(node.left); + if (node.right != null) q.Enqueue(node.right); + } + res.Add(level.ToList()); + } + + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -457,6 +540,55 @@ class Solution { } ``` +```csharp +/** + * Definition for a binary tree node. + * public class TreeNode { + * public int val; + * public TreeNode left; + * public TreeNode right; + * public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +public class Solution { + public List> ZigzagLevelOrder(TreeNode root) { + var res = new List>(); + + void Dfs(TreeNode node, int depth) { + if (node == null) return; + if (depth == res.Count) { + res.Add(new List()); + } + res[depth].Add(node.val); + Dfs(node.left, depth + 1); + Dfs(node.right, depth + 1); + } + + Dfs(root, 0); + + for (int i = 0; i < res.Count; i++) { + if ((i & 1) == 1) { + var level = res[i]; + int l = 0, r = level.Count - 1; + while (l < r) { + int temp = level[l]; + level[l] = level[r]; + level[r] = temp; + l++; + r--; + } + } + } + + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -639,6 +771,62 @@ class Solution { } ``` +```csharp +/** + * Definition for a binary tree node. + * public class TreeNode { + * public int val; + * public TreeNode left; + * public TreeNode right; + * public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +public class Solution { + public List> ZigzagLevelOrder(TreeNode root) { + if (root == null) return new List>(); + + var res = new List>(); + var stack = new Stack<(TreeNode, int)>(); + stack.Push((root, 0)); + + while (stack.Count > 0) { + var (node, depth) = stack.Pop(); + if (depth == res.Count) { + res.Add(new List()); + } + res[depth].Add(node.val); + + if (node.right != null) { + stack.Push((node.right, depth + 1)); + } + if (node.left != null) { + stack.Push((node.left, depth + 1)); + } + } + + for (int i = 0; i < res.Count; i++) { + if ((i % 2) == 1) { + var level = res[i]; + int l = 0, r = level.Count - 1; + while (l < r) { + int temp = level[l]; + level[l] = level[r]; + level[r] = temp; + l++; + r--; + } + } + } + + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity diff --git a/articles/maximum-points-you-can-obtain-from-cards.md b/articles/maximum-points-you-can-obtain-from-cards.md index 87d28bbd8..242f43d1d 100644 --- a/articles/maximum-points-you-can-obtain-from-cards.md +++ b/articles/maximum-points-you-can-obtain-from-cards.md @@ -97,6 +97,31 @@ class Solution { } ``` +```csharp +public class Solution { + public int MaxScore(int[] cardPoints, int k) { + int n = cardPoints.Length; + int res = 0; + + for (int left = 0; left <= k; left++) { + int leftSum = 0; + for (int i = 0; i < left; i++) { + leftSum += cardPoints[i]; + } + + int rightSum = 0; + for (int i = n - (k - left); i < n; i++) { + rightSum += cardPoints[i]; + } + + res = Math.Max(res, leftSum + rightSum); + } + + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -217,6 +242,32 @@ class Solution { } ``` +```csharp +public class Solution { + public int MaxScore(int[] cardPoints, int k) { + int n = cardPoints.Length; + + int[] prefix = new int[n + 1]; + for (int i = 0; i < n; i++) { + prefix[i + 1] = prefix[i] + cardPoints[i]; + } + + int[] suffix = new int[n + 1]; + for (int i = n - 1; i >= 0; i--) { + suffix[i] = suffix[i + 1] + cardPoints[i]; + } + + int res = 0; + for (int left = 0; left <= k; left++) { + int right = k - left; + res = Math.Max(res, prefix[left] + suffix[n - right]); + } + + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -345,6 +396,37 @@ class Solution { } ``` +```csharp +public class Solution { + public int MaxScore(int[] cardPoints, int k) { + int n = cardPoints.Length; + int windowSize = n - k; + + if (windowSize == 0) { + int sum = 0; + foreach (int x in cardPoints) sum += x; + return sum; + } + + int total = 0; + int minWindowSum = int.MaxValue; + int curSum = 0; + + for (int i = 0; i < n; i++) { + total += cardPoints[i]; + curSum += cardPoints[i]; + + if (i >= windowSize - 1) { + minWindowSum = Math.Min(minWindowSum, curSum); + curSum -= cardPoints[i - windowSize + 1]; + } + } + + return total - minWindowSum; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -453,6 +535,28 @@ class Solution { } ``` +```csharp +public class Solution { + public int MaxScore(int[] cardPoints, int k) { + int l = 0, r = cardPoints.Length - k; + int total = 0; + for (int i = r; i < cardPoints.Length; i++) { + total += cardPoints[i]; + } + int res = total; + + while (r < cardPoints.Length) { + total += cardPoints[l] - cardPoints[r]; + res = Math.Max(res, total); + l++; + r++; + } + + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity diff --git a/articles/middle-of-the-linked-list.md b/articles/middle-of-the-linked-list.md index 9d1f36d04..82be33585 100644 --- a/articles/middle-of-the-linked-list.md +++ b/articles/middle-of-the-linked-list.md @@ -94,6 +94,31 @@ class Solution { } ``` +```csharp +/** + * Definition for singly-linked list. + * 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 MiddleNode(ListNode head) { + List arr = new List(); + ListNode cur = head; + while (cur != null) { + arr.Add(cur); + cur = cur.next; + } + return arr[arr.Count / 2]; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -225,6 +250,39 @@ class Solution { } ``` +```csharp +/** + * Definition for singly-linked list. + * 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 MiddleNode(ListNode head) { + int n = 0; + ListNode cur = head; + while (cur != null) { + cur = cur.next; + n++; + } + + n /= 2; + cur = head; + while (n > 0) { + cur = cur.next; + n--; + } + + return cur; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -332,6 +390,30 @@ class Solution { } ``` +```csharp +/** + * Definition for singly-linked list. + * 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 MiddleNode(ListNode head) { + ListNode slow = head, fast = head; + while (fast != null && fast.next != null) { + slow = slow.next; + fast = fast.next.next; + } + return slow; + } +} +``` + ::tabs-end ### Time & Space Complexity diff --git a/articles/two-city-scheduling.md b/articles/two-city-scheduling.md index dc8a3e6e9..26661570e 100644 --- a/articles/two-city-scheduling.md +++ b/articles/two-city-scheduling.md @@ -110,6 +110,30 @@ class Solution { } ``` +```csharp +public class Solution { + public int TwoCitySchedCost(int[][] costs) { + int n = costs.Length / 2; + + int Dfs(int i, int aCount, int bCount) { + if (i == costs.Length) return 0; + + int res = int.MaxValue; + if (aCount > 0) { + res = costs[i][0] + Dfs(i + 1, aCount - 1, bCount); + } + + if (bCount > 0) { + res = Math.Min(res, costs[i][1] + Dfs(i + 1, aCount, bCount - 1)); + } + return res; + } + + return Dfs(0, n, n); + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -256,6 +280,38 @@ class Solution { } ``` +```csharp +public class Solution { + public int TwoCitySchedCost(int[][] costs) { + int n = costs.Length / 2; + int[,] dp = new int[n + 1, n + 1]; + for (int i = 0; i <= n; i++) { + for (int j = 0; j <= n; j++) { + dp[i, j] = -1; + } + } + + int Dfs(int i, int aCount, int bCount) { + if (i == costs.Length) return 0; + if (dp[aCount, bCount] != -1) return dp[aCount, bCount]; + + int res = int.MaxValue; + if (aCount > 0) { + res = costs[i][0] + Dfs(i + 1, aCount - 1, bCount); + } + if (bCount > 0) { + res = Math.Min(res, costs[i][1] + Dfs(i + 1, aCount, bCount - 1)); + } + + dp[aCount, bCount] = res; + return res; + } + + return Dfs(0, n, n); + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -381,6 +437,32 @@ class Solution { } ``` +```csharp +public class Solution { + public int TwoCitySchedCost(int[][] costs) { + int n = costs.Length / 2; + int[,] dp = new int[n + 1, n + 1]; + + for (int aCount = 0; aCount <= n; aCount++) { + for (int bCount = 0; bCount <= n; bCount++) { + int i = aCount + bCount; + if (i == 0) continue; + + dp[aCount, bCount] = int.MaxValue; + if (aCount > 0) { + dp[aCount, bCount] = Math.Min(dp[aCount, bCount], dp[aCount - 1, bCount] + costs[i - 1][0]); + } + if (bCount > 0) { + dp[aCount, bCount] = Math.Min(dp[aCount, bCount], dp[aCount, bCount - 1] + costs[i - 1][1]); + } + } + } + + return dp[n, n]; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -507,6 +589,33 @@ class Solution { } ``` +```csharp +public class Solution { + public int TwoCitySchedCost(int[][] costs) { + int n = costs.Length / 2; + int[] dp = new int[n + 1]; + + for (int aCount = 0; aCount <= n; aCount++) { + for (int bCount = 0; bCount <= n; bCount++) { + int i = aCount + bCount; + if (i == 0) continue; + + int tmp = dp[bCount]; + dp[bCount] = int.MaxValue; + if (aCount > 0) { + dp[bCount] = Math.Min(dp[bCount], tmp + costs[i - 1][0]); + } + if (bCount > 0) { + dp[bCount] = Math.Min(dp[bCount], dp[bCount - 1] + costs[i - 1][1]); + } + } + } + + return dp[n]; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -617,6 +726,29 @@ class Solution { } ``` +```csharp +public class Solution { + public int TwoCitySchedCost(int[][] costs) { + List diffs = new List(); + foreach (var cost in costs) { + diffs.Add(new int[] { cost[1] - cost[0], cost[0], cost[1] }); + } + + diffs.Sort((a, b) => a[0].CompareTo(b[0])); + int res = 0; + for (int i = 0; i < diffs.Count; i++) { + if (i < diffs.Count / 2) { + res += diffs[i][2]; + } else { + res += diffs[i][1]; + } + } + + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -691,6 +823,22 @@ class Solution { } ``` +```csharp +public class Solution { + public int TwoCitySchedCost(int[][] costs) { + Array.Sort(costs, (a, b) => (a[1] - a[0]).CompareTo(b[1] - b[0])); + int n = costs.Length / 2; + int res = 0; + + for (int i = 0; i < n; i++) { + res += costs[i][1] + costs[i + n][0]; + } + + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity From 7958d2ebe49118bf5b6aeb41ff013d1f82eaf09b Mon Sep 17 00:00:00 2001 From: Sri Hari Date: Wed, 1 Oct 2025 10:04:08 +0530 Subject: [PATCH 7/9] Added articles --- ...ind-all-numbers-disappeared-in-an-array.md | 79 ++++++++++ articles/path-sum.md | 140 ++++++++++++++++++ articles/triangle.md | 132 +++++++++++++++++ 3 files changed, 351 insertions(+) diff --git a/articles/find-all-numbers-disappeared-in-an-array.md b/articles/find-all-numbers-disappeared-in-an-array.md index 4ae4b6150..c00be1460 100644 --- a/articles/find-all-numbers-disappeared-in-an-array.md +++ b/articles/find-all-numbers-disappeared-in-an-array.md @@ -68,6 +68,24 @@ class Solution { } ``` +```csharp +public class Solution { + public List FindDisappearedNumbers(int[] nums) { + int n = nums.Length; + var store = new HashSet(); + for (int i = 1; i <= n; i++) { + store.Add(i); + } + + foreach (int num in nums) { + store.Remove(num); + } + + return new List(store); + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -165,6 +183,27 @@ class Solution { } ``` +```csharp +public class Solution { + public IList FindDisappearedNumbers(int[] nums) { + int n = nums.Length; + bool[] mark = new bool[n]; + + foreach (int num in nums) { + mark[num - 1] = true; + } + + List res = new List(); + for (int i = 1; i <= n; i++) { + if (!mark[i - 1]) { + res.Add(i); + } + } + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -261,6 +300,27 @@ class Solution { } ``` +```csharp +public class Solution { + public List FindDisappearedNumbers(int[] nums) { + int n = nums.Length; + Array.Sort(nums); + + List res = new List(); + int idx = 0; + for (int num = 1; num <= n; num++) { + while (idx < n && nums[idx] < num) { + idx++; + } + if (idx == n || nums[idx] > num) { + res.Add(num); + } + } + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -350,6 +410,25 @@ class Solution { } ``` +```csharp +public class Solution { + public List FindDisappearedNumbers(int[] nums) { + foreach (int num in nums) { + int i = Math.Abs(num) - 1; + nums[i] = -1 * Math.Abs(nums[i]); + } + + List res = new List(); + for (int i = 0; i < nums.Length; i++) { + if (nums[i] > 0) { + res.Add(i + 1); + } + } + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity diff --git a/articles/path-sum.md b/articles/path-sum.md index 27da53c1e..caae4e343 100644 --- a/articles/path-sum.md +++ b/articles/path-sum.md @@ -124,6 +124,38 @@ class Solution { } ``` +```csharp +/** + * Definition for a binary tree node. + * public class TreeNode { + * public int val; + * public TreeNode left; + * public TreeNode right; + * public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +public class Solution { + public bool HasPathSum(TreeNode root, int targetSum) { + bool Dfs(TreeNode node, int curSum) { + if (node == null) return false; + + curSum += node.val; + if (node.left == null && node.right == null) { + return curSum == targetSum; + } + + return Dfs(node.left, curSum) || Dfs(node.right, curSum); + } + + return Dfs(root, 0); + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -235,6 +267,32 @@ class Solution { } ``` +```csharp +/** + * Definition for a binary tree node. + * public class TreeNode { + * public int val; + * public TreeNode left; + * public TreeNode right; + * public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +public class Solution { + public bool HasPathSum(TreeNode root, int targetSum) { + if (root == null) return false; + + targetSum -= root.val; + return HasPathSum(root.left, targetSum) || + HasPathSum(root.right, targetSum) || + (targetSum == 0 && root.left == null && root.right == null); + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -405,6 +463,47 @@ class Solution { } ``` +```csharp +/** + * Definition for a binary tree node. + * public class TreeNode { + * public int val; + * public TreeNode left; + * public TreeNode right; + * public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +public class Solution { + public bool HasPathSum(TreeNode root, int targetSum) { + if (root == null) return false; + + Stack<(TreeNode, int)> stack = new Stack<(TreeNode, int)>(); + stack.Push((root, targetSum - root.val)); + + while (stack.Count > 0) { + var (node, currSum) = stack.Pop(); + + if (node.left == null && node.right == null && currSum == 0) { + return true; + } + + if (node.right != null) { + stack.Push((node.right, currSum - node.right.val)); + } + if (node.left != null) { + stack.Push((node.left, currSum - node.left.val)); + } + } + + return false; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -575,6 +674,47 @@ class Solution { } ``` +```csharp +/** + * Definition for a binary tree node. + * public class TreeNode { + * public int val; + * public TreeNode left; + * public TreeNode right; + * public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +public class Solution { + public bool HasPathSum(TreeNode root, int targetSum) { + if (root == null) return false; + + Queue<(TreeNode, int)> queue = new Queue<(TreeNode, int)>(); + queue.Enqueue((root, targetSum - root.val)); + + while (queue.Count > 0) { + var (node, currSum) = queue.Dequeue(); + + if (node.left == null && node.right == null && currSum == 0) { + return true; + } + + if (node.left != null) { + queue.Enqueue((node.left, currSum - node.left.val)); + } + if (node.right != null) { + queue.Enqueue((node.right, currSum - node.right.val)); + } + } + + return false; + } +} +``` + ::tabs-end ### Time & Space Complexity diff --git a/articles/triangle.md b/articles/triangle.md index 19505370f..bb709d6a8 100644 --- a/articles/triangle.md +++ b/articles/triangle.md @@ -67,6 +67,21 @@ class Solution { } ``` +```csharp +public class Solution { + public int MinimumTotal(List> triangle) { + int Dfs(int row, int col) { + if (row >= triangle.Count) { + return 0; + } + return triangle[row][col] + Math.Min(Dfs(row + 1, col), Dfs(row + 1, col + 1)); + } + + return Dfs(0, 0); + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -186,6 +201,38 @@ class Solution { } ``` +```csharp +public class Solution { + private int[][] memo; + private List> triangle; + private int INF = int.MaxValue; + + public int MinimumTotal(List> triangle) { + this.triangle = triangle; + memo = new int[triangle.Count][]; + for (int r = 0; r < triangle.Count; r++) { + memo[r] = new int[triangle[r].Count]; + for (int c = 0; c < triangle[r].Count; c++) { + memo[r][c] = INF; + } + } + return Dfs(0, 0); + } + + private int Dfs(int row, int col) { + if (row >= triangle.Count) { + return 0; + } + if (memo[row][col] != INF) { + return memo[row][col]; + } + + memo[row][col] = triangle[row][col] + Math.Min(Dfs(row + 1, col), Dfs(row + 1, col + 1)); + return memo[row][col]; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -282,6 +329,30 @@ class Solution { } ``` +```csharp +public class Solution { + public int MinimumTotal(List> triangle) { + int n = triangle.Count; + int[][] dp = new int[n][]; + for (int i = 0; i < n; i++) { + dp[i] = new int[triangle[i].Count]; + } + + for (int c = 0; c < triangle[n - 1].Count; c++) { + dp[n - 1][c] = triangle[n - 1][c]; + } + + for (int row = n - 2; row >= 0; row--) { + for (int col = 0; col < triangle[row].Count; col++) { + dp[row][col] = triangle[row][col] + Math.Min(dp[row + 1][col], dp[row + 1][col + 1]); + } + } + + return dp[0][0]; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -386,6 +457,34 @@ class Solution { } ``` +```csharp +public class Solution { + public int MinimumTotal(List> triangle) { + int n = triangle.Count; + int[] dp = new int[triangle[0].Count]; + for (int i = 0; i < triangle[0].Count; i++) { + dp[i] = triangle[0][i]; + } + + for (int row = 1; row < n; row++) { + int[] nxtDp = new int[triangle[row].Count]; + nxtDp[0] = dp[0] + triangle[row][0]; + for (int col = 1; col < triangle[row].Count - 1; col++) { + nxtDp[col] = triangle[row][col] + Math.Min(dp[col], dp[col - 1]); + } + nxtDp[triangle[row].Count - 1] = dp[dp.Length - 1] + triangle[row][triangle[row].Count - 1]; + dp = nxtDp; + } + + int ans = dp[0]; + for (int i = 1; i < dp.Length; i++) { + ans = Math.Min(ans, dp[i]); + } + return ans; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -471,6 +570,26 @@ class Solution { } ``` +```csharp +public class Solution { + public int MinimumTotal(List> triangle) { + int n = triangle.Count; + int[] dp = new int[triangle[n - 1].Count]; + for (int i = 0; i < triangle[n - 1].Count; i++) { + dp[i] = triangle[n - 1][i]; + } + + for (int row = n - 2; row >= 0; row--) { + for (int col = 0; col < triangle[row].Count; col++) { + dp[col] = triangle[row][col] + Math.Min(dp[col], dp[col + 1]); + } + } + + return dp[0]; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -542,6 +661,19 @@ class Solution { } ``` +```csharp +public class Solution { + public int MinimumTotal(List> triangle) { + for (int row = triangle.Count - 2; row >= 0; row--) { + for (int col = 0; col < triangle[row].Count; col++) { + triangle[row][col] += Math.Min(triangle[row + 1][col], triangle[row + 1][col + 1]); + } + } + return triangle[0][0]; + } +} +``` + ::tabs-end ### Time & Space Complexity From f8c7e51d85bf8680f41bb8e9d2f37d012f6596d6 Mon Sep 17 00:00:00 2001 From: Sri Hari Date: Wed, 1 Oct 2025 17:50:28 +0530 Subject: [PATCH 8/9] Added articles --- articles/assign-cookies.md | 68 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/articles/assign-cookies.md b/articles/assign-cookies.md index 8c471f4f4..9aa5a0032 100644 --- a/articles/assign-cookies.md +++ b/articles/assign-cookies.md @@ -111,6 +111,33 @@ class Solution { } ``` +```csharp +public class Solution { + public int FindContentChildren(int[] g, int[] s) { + Array.Sort(s); + int res = 0; + + foreach (int i in g) { + int minIdx = -1; + for (int j = 0; j < s.Length; j++) { + if (s[j] < i) continue; + + if (minIdx == -1 || s[minIdx] > s[j]) { + minIdx = j; + } + } + + if (minIdx != -1) { + s[minIdx] = -1; + res++; + } + } + + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -210,6 +237,28 @@ class Solution { } ``` +```csharp +public class Solution { + public int FindContentChildren(int[] g, int[] s) { + Array.Sort(g); + Array.Sort(s); + + int i = 0, j = 0; + while (i < g.Length) { + while (j < s.Length && g[i] > s[j]) { + j++; + } + if (j == s.Length) { + break; + } + i++; + j++; + } + return i; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -291,6 +340,25 @@ class Solution { } ``` +```csharp +public class Solution { + public int FindContentChildren(int[] g, int[] s) { + Array.Sort(g); + Array.Sort(s); + + int i = 0, j = 0; + while (i < g.Length && j < s.Length) { + if (g[i] <= s[j]) { + i++; + } + j++; + } + + return i; + } +} +``` + ::tabs-end ### Time & Space Complexity From 0711400b6a8c38820e656c6da923a7d75f4ed0f5 Mon Sep 17 00:00:00 2001 From: Sri Hari Date: Thu, 2 Oct 2025 12:55:44 +0530 Subject: [PATCH 9/9] Added articles --- ...inimize-the-maximum-difference-of-pairs.md | 151 ++++++++++++++++++ 1 file changed, 151 insertions(+) diff --git a/articles/minimize-the-maximum-difference-of-pairs.md b/articles/minimize-the-maximum-difference-of-pairs.md index 04d2f5cd7..ec8d1fdc0 100644 --- a/articles/minimize-the-maximum-difference-of-pairs.md +++ b/articles/minimize-the-maximum-difference-of-pairs.md @@ -110,6 +110,41 @@ class Solution { } ``` +```csharp +public class Solution { + private int n; + private int p; + private int[] nums; + private Dictionary<(int, int), int> dp; + + public int MinimizeMax(int[] nums, int p) { + Array.Sort(nums); + this.nums = nums; + this.p = p; + this.n = nums.Length; + dp = new Dictionary<(int, int), int>(); + return Dfs(0, 0); + } + + private int Dfs(int i, int pairs) { + if (pairs == p) { + return 0; + } + if (i >= n - 1) { + return int.MaxValue / 2; + } + if (dp.ContainsKey((i, pairs))) { + return dp[(i, pairs)]; + } + + int take = Math.Max(nums[i + 1] - nums[i], Dfs(i + 2, pairs + 1)); + int skip = Dfs(i + 1, pairs); + dp[(i, pairs)] = Math.Min(take, skip); + return dp[(i, pairs)]; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -240,6 +275,42 @@ class Solution { } ``` +```csharp +public class Solution { + public int MinimizeMax(int[] nums, int p) { + int n = nums.Length; + Array.Sort(nums); + + int INF = int.MaxValue / 2; + int[,] dp = new int[n + 1, p + 1]; + + for (int i = 0; i <= n; i++) { + for (int j = 0; j <= p; j++) { + dp[i, j] = INF; + } + } + + for (int i = 0; i <= n; i++) { + dp[i, 0] = 0; + } + + for (int i = n - 2; i >= 0; i--) { + for (int pairs = 1; pairs <= p; pairs++) { + int take = INF; + if (i + 1 < n) { + take = Math.Max(nums[i + 1] - nums[i], dp[i + 2, pairs - 1]); + } + + int skip = dp[i + 1, pairs]; + dp[i, pairs] = Math.Min(take, skip); + } + } + + return dp[0, p]; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -386,6 +457,48 @@ class Solution { } ``` +```csharp +public class Solution { + public int MinimizeMax(int[] nums, int p) { + int n = nums.Length; + Array.Sort(nums); + + int INF = int.MaxValue / 2; + int[] dp = new int[p + 1]; + int[] dp1 = new int[p + 1]; + int[] dp2 = new int[p + 1]; + + for (int j = 0; j <= p; j++) { + dp[j] = INF; + dp1[j] = INF; + dp2[j] = INF; + } + + dp[0] = dp1[0] = dp2[0] = 0; + + for (int i = n - 1; i >= 0; i--) { + for (int pairs = 1; pairs <= p; pairs++) { + int take = INF; + if (i + 1 < n) { + take = Math.Max(nums[i + 1] - nums[i], dp2[pairs - 1]); + } + int skip = dp1[pairs]; + dp[pairs] = Math.Min(take, skip); + } + + dp2 = (int[])dp1.Clone(); + dp1 = (int[])dp.Clone(); + + dp = new int[p + 1]; + for (int j = 0; j <= p; j++) dp[j] = INF; + dp[0] = 0; + } + + return dp1[p]; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -557,6 +670,44 @@ class Solution { } ``` +```csharp +public class Solution { + public int MinimizeMax(int[] nums, int p) { + if (p == 0) return 0; + Array.Sort(nums); + + bool IsValid(int threshold) { + int i = 0, cnt = 0; + while (i < nums.Length - 1) { + if (Math.Abs(nums[i] - nums[i + 1]) <= threshold) { + cnt++; + i += 2; + } else { + i++; + } + if (cnt == p) return true; + } + return false; + } + + int l = 0, r = nums[nums.Length - 1] - nums[0]; + int res = r; + + while (l <= r) { + int m = l + (r - l) / 2; + if (IsValid(m)) { + res = m; + r = m - 1; + } else { + l = m + 1; + } + } + + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity