From fbbe45cb87d39c82459df63436132db286f9a620 Mon Sep 17 00:00:00 2001 From: Sri Hari <94112314+Srihari2222@users.noreply.github.com> Date: Mon, 1 Sep 2025 01:19:23 +0530 Subject: [PATCH] Sri Hari: Batch-9/Added Articles (#4754) * Batch-9/Neetcode-ALL/Added-articles * Batch-9/Neetcode-ALL/Added-articles * Batch-9/Neetcode-ALL/Added-articles --- ...ee-from-inorder-and-postorder-traversal.md | 122 +++- articles/count-prefix-and-suffix-pairs-i.md | 535 +++++++++++++++++ articles/count-servers-that-communicate.md | 536 ++++++++++++++++++ .../counting-words-with-a-given-prefix.md | 482 ++++++++++++++++ .../first-unique-character-in-a-string.md | 83 +++ articles/insert-delete-getrandom-o1.md | 79 +++ articles/isomorphic-strings.md | 43 ++ articles/paint-house.md | 102 +++- articles/path-with-maximum-probability.md | 183 +++++- articles/power-of-two.md | 68 +++ .../remove-sub-folders-from-the-filesystem.md | 497 ++++++++++++++++ articles/shortest-bridge.md | 242 ++++++++ articles/sort-array-by-parity.md | 72 +++ articles/subarray-product-less-than-k.md | 106 +++- articles/text-justification.md | 43 ++ 15 files changed, 3161 insertions(+), 32 deletions(-) create mode 100644 articles/count-prefix-and-suffix-pairs-i.md create mode 100644 articles/count-servers-that-communicate.md create mode 100644 articles/counting-words-with-a-given-prefix.md create mode 100644 articles/remove-sub-folders-from-the-filesystem.md diff --git a/articles/construct-binary-tree-from-inorder-and-postorder-traversal.md b/articles/construct-binary-tree-from-inorder-and-postorder-traversal.md index 5a538b401..69b2888b0 100644 --- a/articles/construct-binary-tree-from-inorder-and-postorder-traversal.md +++ b/articles/construct-binary-tree-from-inorder-and-postorder-traversal.md @@ -142,6 +142,45 @@ 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 BuildTree(int[] inorder, int[] postorder) { + if (postorder.Length == 0 || inorder.Length == 0) { + return null; + } + + int rootVal = postorder[postorder.Length - 1]; + TreeNode root = new TreeNode(rootVal); + + int mid = Array.IndexOf(inorder, rootVal); + + int[] leftInorder = inorder[..mid]; + int[] rightInorder = inorder[(mid + 1)..]; + + int[] leftPostorder = postorder[..mid]; + int[] rightPostorder = postorder[mid..^1]; + + root.left = BuildTree(leftInorder, leftPostorder); + root.right = BuildTree(rightInorder, rightPostorder); + + return root; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -301,6 +340,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 { + int[] postorder; + Dictionary inorderIdx; + int idx; + + public TreeNode BuildTree(int[] inorder, int[] postorder) { + this.postorder = postorder; + inorderIdx = new Dictionary(); + for (int i = 0; i < inorder.Length; i++) { + inorderIdx[inorder[i]] = i; + } + idx = postorder.Length - 1; + return Dfs(0, inorder.Length - 1); + } + + private TreeNode Dfs(int l, int r) { + if (l > r) return null; + + TreeNode root = new TreeNode(postorder[idx--]); + int i = inorderIdx[root.val]; + root.right = Dfs(i + 1, r); + root.left = Dfs(l, i - 1); + return root; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -468,9 +548,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 { + int postIdx, inIdx; + int[] inorder, postorder; + + public TreeNode BuildTree(int[] inorder, int[] postorder) { + this.inorder = inorder; + this.postorder = postorder; + postIdx = inIdx = postorder.Length - 1; + return Dfs(int.MaxValue); + } + + private TreeNode Dfs(int limit) { + if (postIdx < 0) return null; + if (inorder[inIdx] == limit) { + inIdx--; + return null; + } + + TreeNode root = new TreeNode(postorder[postIdx--]); + root.right = Dfs(root.val); + root.left = Dfs(limit); + return root; + } +} +``` + ::tabs-end ### Time & Space Complexity - Time complexity: $O(n)$ -- Space complexity: $O(n)$ for recursion stack. +- Space complexity: $O(n)$ for recursion stack. \ No newline at end of file diff --git a/articles/count-prefix-and-suffix-pairs-i.md b/articles/count-prefix-and-suffix-pairs-i.md new file mode 100644 index 000000000..5d10f4521 --- /dev/null +++ b/articles/count-prefix-and-suffix-pairs-i.md @@ -0,0 +1,535 @@ +## 1. Brute Force + +::tabs-start + +```python +class Solution: + def countPrefixSuffixPairs(self, words: List[str]) -> int: + def isPrefixAndSuffix(s1, s2): + if len(s1) > len(s2): + return False + + for i in range(len(s1)): + if s1[i] != s2[i]: + return False + + j = 0 + for i in range(len(s2) - len(s1), len(s2)): + if s1[j] != s2[i]: + return False + j += 1 + + return True + + res = 0 + for i in range(len(words)): + for j in range(i + 1, len(words)): + res += isPrefixAndSuffix(words[i], words[j]) + return res +``` + +```java +public class Solution { + public int countPrefixSuffixPairs(String[] words) { + int res = 0; + for (int i = 0; i < words.length; i++) { + for (int j = i + 1; j < words.length; j++) { + if (isPrefixAndSuffix(words[i], words[j])) { + res++; + } + } + } + return res; + } + + private boolean isPrefixAndSuffix(String s1, String s2) { + if (s1.length() > s2.length()) return false; + + for (int i = 0; i < s1.length(); i++) { + if (s1.charAt(i) != s2.charAt(i)) return false; + } + + int j = 0; + for (int i = s2.length() - s1.length(); i < s2.length(); i++) { + if (s1.charAt(j) != s2.charAt(i)) return false; + j++; + } + + return true; + } +} +``` + +```cpp +class Solution { +public: + int countPrefixSuffixPairs(vector& words) { + int res = 0; + for (int i = 0; i < words.size(); i++) { + for (int j = i + 1; j < words.size(); j++) { + if (isPrefixAndSuffix(words[i], words[j])) { + res++; + } + } + } + return res; + } + + bool isPrefixAndSuffix(string s1, string s2) { + if (s1.size() > s2.size()) return false; + + for (int i = 0; i < s1.size(); i++) { + if (s1[i] != s2[i]) return false; + } + + int j = 0; + for (int i = s2.size() - s1.size(); i < s2.size(); i++) { + if (s1[j] != s2[i]) return false; + j++; + } + + return true; + } +}; +``` + +```javascript +class Solution { + /** + * @param {string[]} words + * @return {number} + */ + countPrefixSuffixPairs(words) { + const isPrefixAndSuffix = (s1, s2) => { + if (s1.length > s2.length) return false; + + for (let i = 0; i < s1.length; i++) { + if (s1[i] !== s2[i]) return false; + } + + let j = 0; + for (let i = s2.length - s1.length; i < s2.length; i++) { + if (s1[j] !== s2[i]) return false; + j++; + } + + return true; + }; + + let res = 0; + for (let i = 0; i < words.length; i++) { + for (let j = i + 1; j < words.length; j++) { + if (isPrefixAndSuffix(words[i], words[j])) { + res++; + } + } + } + return res; + } +} +``` + +```csharp +public class Solution { + public int CountPrefixSuffixPairs(string[] words) { + int res = 0; + for (int i = 0; i < words.Length; i++) { + for (int j = i + 1; j < words.Length; j++) { + if (IsPrefixAndSuffix(words[i], words[j])) { + res++; + } + } + } + return res; + } + + private bool IsPrefixAndSuffix(string s1, string s2) { + if (s1.Length > s2.Length) return false; + + for (int i = 0; i < s1.Length; i++) { + if (s1[i] != s2[i]) return false; + } + + int j = 0; + for (int i = s2.Length - s1.Length; i < s2.Length; i++) { + if (s1[j] != s2[i]) return false; + j++; + } + + return true; + } +} +``` + +::tabs-end + +### Time & Space Complexity + +* Time complexity: $O(n ^ 2 * m)$ +* Space complexity: $O(1)$ + +> Where $n$ is the size of the input array $words$, and $m$ is the maximum length of a string. + +--- + +## 2. Brute Force (Using Built-In Function) + +::tabs-start + +```python +class Solution: + def countPrefixSuffixPairs(self, words: List[str]) -> int: + res = 0 + + for i in range(len(words)): + for j in range(i + 1, len(words)): + w1, w2 = words[i], words[j] + if w2.startswith(w1) and w2.endswith(w1): + res += 1 + + return res +``` + +```java +public class Solution { + public int countPrefixSuffixPairs(String[] words) { + int res = 0; + for (int i = 0; i < words.length; i++) { + for (int j = i + 1; j < words.length; j++) { + String w1 = words[i], w2 = words[j]; + if (w2.startsWith(w1) && w2.endsWith(w1)) { + res++; + } + } + } + return res; + } +} +``` + +```cpp +class Solution { +public: + int countPrefixSuffixPairs(vector& words) { + int res = 0; + for (int i = 0; i < words.size(); i++) { + for (int j = i + 1; j < words.size(); j++) { + string w1 = words[i], w2 = words[j]; + if (w2.rfind(w1, 0) == 0 && + w2.compare(w2.size() - w1.size(), w1.size(), w1) == 0) { + res++; + } + } + } + return res; + } +}; +``` + +```javascript +class Solution { + /** + * @param {string[]} words + * @return {number} + */ + countPrefixSuffixPairs(words) { + let res = 0; + for (let i = 0; i < words.length; i++) { + for (let j = i + 1; j < words.length; j++) { + let w1 = words[i], w2 = words[j]; + if (w2.startsWith(w1) && w2.endsWith(w1)) { + res++; + } + } + } + return res; + } +} +``` + +```csharp +public class Solution { + public int CountPrefixSuffixPairs(string[] words) { + int res = 0; + for (int i = 0; i < words.Length; i++) { + for (int j = i + 1; j < words.Length; j++) { + string w1 = words[i], w2 = words[j]; + if (w2.StartsWith(w1) && w2.EndsWith(w1)) { + res++; + } + } + } + return res; + } +} +``` + +::tabs-end + +### Time & Space Complexity + +* Time complexity: $O(n ^ 2 * m)$ +* Space complexity: $O(1)$ + +> Where $n$ is the size of the input array $words$, and $m$ is the maximum length of a string. + +--- + +## 3. Trie + +::tabs-start + +```python +class TrieNode: + def __init__(self): + self.children = {} + self.count = 0 + +class Trie: + def __init__(self): + self.root = TrieNode() + + def add(self, w: str) -> None: + cur = self.root + for c1, c2 in zip(w, reversed(w)): + if (c1, c2) not in cur.children: + cur.children[(c1, c2)] = TrieNode() + cur = cur.children[(c1, c2)] + cur.count += 1 + + def count(self, w: str) -> int: + cur = self.root + for c1, c2 in zip(w, reversed(w)): + if (c1, c2) not in cur.children: + return 0 + cur = cur.children[(c1, c2)] + return cur.count + +class Solution: + def countPrefixSuffixPairs(self, words: List[str]) -> int: + res = 0 + root = Trie() + + for w in reversed(words): + res += root.count(w) + root.add(w) + + return res +``` + +```java +class TrieNode { + Map children = new HashMap<>(); + int count = 0; +} + +class Trie { + TrieNode root = new TrieNode(); + + void add(String w) { + TrieNode cur = root; + int n = w.length(); + for (int i = 0; i < n; i++) { + String key = "" + w.charAt(i) + w.charAt(n - 1 - i); + cur.children.putIfAbsent(key, new TrieNode()); + cur = cur.children.get(key); + cur.count++; + } + } + + int count(String w) { + TrieNode cur = root; + int n = w.length(); + for (int i = 0; i < n; i++) { + String key = "" + w.charAt(i) + w.charAt(n - 1 - i); + if (!cur.children.containsKey(key)) return 0; + cur = cur.children.get(key); + } + return cur.count; + } +} + +public class Solution { + public int countPrefixSuffixPairs(String[] words) { + int res = 0; + Trie root = new Trie(); + for (int i = words.length - 1; i >= 0; i--) { + res += root.count(words[i]); + root.add(words[i]); + } + return res; + } +} +``` + +```cpp +class TrieNode { +public: + unordered_map children; + int count = 0; +}; + +class Trie { +public: + TrieNode* root; + Trie() { + root = new TrieNode(); + } + + void add(string w) { + TrieNode* cur = root; + int n = w.size(); + for (int i = 0; i < n; i++) { + string key = string(1, w[i]) + w[n - 1 - i]; + if (cur->children.find(key) == cur->children.end()) { + cur->children[key] = new TrieNode(); + } + cur = cur->children[key]; + cur->count++; + } + } + + int count(string w) { + TrieNode* cur = root; + int n = w.size(); + for (int i = 0; i < n; i++) { + string key = string(1, w[i]) + w[n - 1 - i]; + if (cur->children.find(key) == cur->children.end()) return 0; + cur = cur->children[key]; + } + return cur->count; + } +}; + +class Solution { +public: + int countPrefixSuffixPairs(vector& words) { + int res = 0; + Trie root; + for (int i = words.size() - 1; i >= 0; i--) { + res += root.count(words[i]); + root.add(words[i]); + } + return res; + } +}; +``` + +```javascript +class TrieNode { + constructor() { + this.children = new Map(); + this.count = 0; + } +} + +class Trie { + constructor() { + this.root = new TrieNode(); + } + + /** + * @param {string} w + * @return {void} + */ + add(w) { + let cur = this.root; + let n = w.length; + for (let i = 0; i < n; i++) { + let key = w[i] + w[n - 1 - i]; + if (!cur.children.has(key)) { + cur.children.set(key, new TrieNode()); + } + cur = cur.children.get(key); + cur.count++; + } + } + + /** + * @param {string} words + * @return {number} + */ + count(w) { + let cur = this.root; + let n = w.length; + for (let i = 0; i < n; i++) { + let key = w[i] + w[n - 1 - i]; + if (!cur.children.has(key)) return 0; + cur = cur.children.get(key); + } + return cur.count; + } +} + +class Solution { + /** + * @param {string[]} words + * @return {number} + */ + countPrefixSuffixPairs(words) { + let res = 0; + let root = new Trie(); + for (let i = words.length - 1; i >= 0; i--) { + res += root.count(words[i]); + root.add(words[i]); + } + return res; + } +} +``` + +```csharp +public class TrieNode { + public Dictionary children = new Dictionary(); + public int count = 0; +} + +public class Trie { + public TrieNode root = new TrieNode(); + + public void Add(string w) { + TrieNode cur = root; + int n = w.Length; + for (int i = 0; i < n; i++) { + string key = w[i].ToString() + w[n - 1 - i]; + if (!cur.children.ContainsKey(key)) { + cur.children[key] = new TrieNode(); + } + cur = cur.children[key]; + cur.count++; + } + } + + public int Count(string w) { + TrieNode cur = root; + int n = w.Length; + for (int i = 0; i < n; i++) { + string key = w[i].ToString() + w[n - 1 - i]; + if (!cur.children.ContainsKey(key)) return 0; + cur = cur.children[key]; + } + return cur.count; + } +} + +public class Solution { + public int CountPrefixSuffixPairs(string[] words) { + int res = 0; + Trie root = new Trie(); + for (int i = words.Length - 1; i >= 0; i--) { + res += root.Count(words[i]); + root.Add(words[i]); + } + return res; + } +} +``` + +::tabs-end + +### Time & Space Complexity + +* Time complexity: $O(n * m)$ +* Space complexity: $O(n * m)$ + +> Where $n$ is the size of the input array $words$, and $m$ is the maximum length of a string. \ No newline at end of file diff --git a/articles/count-servers-that-communicate.md b/articles/count-servers-that-communicate.md new file mode 100644 index 000000000..1220275a5 --- /dev/null +++ b/articles/count-servers-that-communicate.md @@ -0,0 +1,536 @@ +## 1. Brute Force + +::tabs-start + +```python +class Solution: + def countServers(self, grid: List[List[int]]) -> int: + m, n = len(grid), len(grid[0]) + res = 0 + + for r in range(m): + for c in range(n): + if grid[r][c] == 0: + continue + + found = False + for col in range(n): + if col != c and grid[r][col] == 1: + found = True + break + + if not found: + for row in range(m): + if row != r and grid[row][c] == 1: + found = True + break + + if found: + res += 1 + + return res +``` + +```java +public class Solution { + public int countServers(int[][] grid) { + int m = grid.length, n = grid[0].length; + int res = 0; + + for (int r = 0; r < m; r++) { + for (int c = 0; c < n; c++) { + if (grid[r][c] == 0) continue; + + boolean found = false; + for (int col = 0; col < n; col++) { + if (col != c && grid[r][col] == 1) { + found = true; + break; + } + } + + if (!found) { + for (int row = 0; row < m; row++) { + if (row != r && grid[row][c] == 1) { + found = true; + break; + } + } + } + + if (found) res++; + } + } + + return res; + } +} +``` + +```cpp +class Solution { +public: + int countServers(vector>& grid) { + int m = grid.size(), n = grid[0].size(); + int res = 0; + + for (int r = 0; r < m; r++) { + for (int c = 0; c < n; c++) { + if (grid[r][c] == 0) continue; + + bool found = false; + for (int col = 0; col < n; col++) { + if (col != c && grid[r][col] == 1) { + found = true; + break; + } + } + + if (!found) { + for (int row = 0; row < m; row++) { + if (row != r && grid[row][c] == 1) { + found = true; + break; + } + } + } + + if (found) res++; + } + } + + return res; + } +}; +``` + +```javascript +class Solution { + /** + * @param {number[][]} grid + * @return {number} + */ + countServers(grid) { + let m = grid.length, n = grid[0].length; + let res = 0; + + for (let r = 0; r < m; r++) { + for (let c = 0; c < n; c++) { + if (grid[r][c] === 0) continue; + + let found = false; + for (let col = 0; col < n; col++) { + if (col !== c && grid[r][col] === 1) { + found = true; + break; + } + } + + if (!found) { + for (let row = 0; row < m; row++) { + if (row !== r && grid[row][c] === 1) { + found = true; + break; + } + } + } + + if (found) res++; + } + } + + return res; + } +} +``` + +```csharp +public class Solution { + public int CountServers(int[][] grid) { + int m = grid.Length, n = grid[0].Length; + int res = 0; + + for (int r = 0; r < m; r++) { + for (int c = 0; c < n; c++) { + if (grid[r][c] == 0) continue; + + bool found = false; + for (int col = 0; col < n; col++) { + if (col != c && grid[r][col] == 1) { + found = true; + break; + } + } + + if (!found) { + for (int row = 0; row < m; row++) { + if (row != r && grid[row][c] == 1) { + found = true; + break; + } + } + } + + if (found) res++; + } + } + + return res; + } +} +``` + +::tabs-end + +### Time & Space Complexity + +* Time complexity: $O(m * n ^ 2)$ +* Space complexity: $O(1)$ + +> Where $m$ is the number of rows and $n$ is the number of columns of the given matrix $grid$. + +--- + +## 2. Iteration + +::tabs-start + +```python +class Solution: + def countServers(self, grid: List[List[int]]) -> int: + ROWS, COLS = len(grid), len(grid[0]) + row_cnt = [0] * ROWS + col_cnt = [0] * COLS + + for r in range(ROWS): + for c in range(COLS): + if grid[r][c] == 1: + row_cnt[r] += 1 + col_cnt[c] += 1 + + res = 0 + for r in range(ROWS): + for c in range(COLS): + if grid[r][c] and max(row_cnt[r], col_cnt[c]) > 1: + res += 1 + + return res +``` + +```java +public class Solution { + public int countServers(int[][] grid) { + int ROWS = grid.length, COLS = grid[0].length; + int[] row_cnt = new int[ROWS]; + int[] col_cnt = new int[COLS]; + + for (int r = 0; r < ROWS; r++) { + for (int c = 0; c < COLS; c++) { + if (grid[r][c] == 1) { + row_cnt[r]++; + col_cnt[c]++; + } + } + } + + int res = 0; + for (int r = 0; r < ROWS; r++) { + for (int c = 0; c < COLS; c++) { + if (grid[r][c] == 1 && Math.max(row_cnt[r], col_cnt[c]) > 1) { + res++; + } + } + } + + return res; + } +} +``` + +```cpp +class Solution { +public: + int countServers(vector>& grid) { + int ROWS = grid.size(), COLS = grid[0].size(); + vector row_cnt(ROWS, 0), col_cnt(COLS, 0); + + for (int r = 0; r < ROWS; r++) { + for (int c = 0; c < COLS; c++) { + if (grid[r][c] == 1) { + row_cnt[r]++; + col_cnt[c]++; + } + } + } + + int res = 0; + for (int r = 0; r < ROWS; r++) { + for (int c = 0; c < COLS; c++) { + if (grid[r][c] == 1 && max(row_cnt[r], col_cnt[c]) > 1) { + res++; + } + } + } + + return res; + } +}; +``` + +```javascript +class Solution { + /** + * @param {number[][]} grid + * @return {number} + */ + countServers(grid) { + let ROWS = grid.length, COLS = grid[0].length; + let row_cnt = new Array(ROWS).fill(0); + let col_cnt = new Array(COLS).fill(0); + + for (let r = 0; r < ROWS; r++) { + for (let c = 0; c < COLS; c++) { + if (grid[r][c] === 1) { + row_cnt[r]++; + col_cnt[c]++; + } + } + } + + let res = 0; + for (let r = 0; r < ROWS; r++) { + for (let c = 0; c < COLS; c++) { + if (grid[r][c] === 1 && Math.max(row_cnt[r], col_cnt[c]) > 1) { + res++; + } + } + } + + return res; + } +} +``` + +```csharp +public class Solution { + public int CountServers(int[][] grid) { + int ROWS = grid.Length, COLS = grid[0].Length; + int[] row_cnt = new int[ROWS]; + int[] col_cnt = new int[COLS]; + + for (int r = 0; r < ROWS; r++) { + for (int c = 0; c < COLS; c++) { + if (grid[r][c] == 1) { + row_cnt[r]++; + col_cnt[c]++; + } + } + } + + int res = 0; + for (int r = 0; r < ROWS; r++) { + for (int c = 0; c < COLS; c++) { + if (grid[r][c] == 1 && Math.Max(row_cnt[r], col_cnt[c]) > 1) { + res++; + } + } + } + + return res; + } +} +``` + +::tabs-end + +### Time & Space Complexity + +* Time complexity: $O(m * n)$ +* Space complexity: $O(m + n)$ + +> Where $m$ is the number of rows and $n$ is the number of columns of the given matrix $grid$. + +--- + +## 3. Iteration (Space Optimized) + +::tabs-start + +```python +class Solution: + def countServers(self, grid: List[List[int]]) -> int: + res = 0 + ROWS, COLS = len(grid), len(grid[0]) + + # Rows + for r in range(ROWS): + row_sum = sum(grid[r]) + if row_sum <= 1: + continue + res += row_sum + for c in range(COLS): + if grid[r][c]: + grid[r][c] = -1 # Mark + + # Cols + for c in range(COLS): + col_sum = unmarked = 0 + for r in range(ROWS): + col_sum += abs(grid[r][c]) + if grid[r][c] > 0: + unmarked += 1 + elif grid[r][c] < 0: + grid[r][c] = 1 # Unmark + if col_sum >= 2: + res += unmarked + + return res +``` + +```java +public class Solution { + public int countServers(int[][] grid) { + int res = 0; + int ROWS = grid.length, COLS = grid[0].length; + + // Rows + for (int r = 0; r < ROWS; r++) { + int rowSum = 0; + for (int c = 0; c < COLS; c++) { + rowSum += grid[r][c]; + } + if (rowSum <= 1) continue; + res += rowSum; + for (int c = 0; c < COLS; c++) { + if (grid[r][c] == 1) grid[r][c] = -1; // Mark + } + } + + // Cols + for (int c = 0; c < COLS; c++) { + int colSum = 0, unmarked = 0; + for (int r = 0; r < ROWS; r++) { + colSum += Math.abs(grid[r][c]); + if (grid[r][c] > 0) unmarked++; + else if (grid[r][c] < 0) grid[r][c] = 1; // Unmark + } + if (colSum >= 2) res += unmarked; + } + + return res; + } +} +``` + +```cpp +class Solution { +public: + int countServers(vector>& grid) { + int res = 0; + int ROWS = grid.size(), COLS = grid[0].size(); + + // Rows + for (int r = 0; r < ROWS; r++) { + int rowSum = accumulate(grid[r].begin(), grid[r].end(), 0); + if (rowSum <= 1) continue; + res += rowSum; + for (int c = 0; c < COLS; c++) { + if (grid[r][c] == 1) grid[r][c] = -1; // Mark + } + } + + // Cols + for (int c = 0; c < COLS; c++) { + int colSum = 0, unmarked = 0; + for (int r = 0; r < ROWS; r++) { + colSum += abs(grid[r][c]); + if (grid[r][c] > 0) unmarked++; + else if (grid[r][c] < 0) grid[r][c] = 1; // Unmark + } + if (colSum >= 2) res += unmarked; + } + + return res; + } +}; +``` + +```javascript +class Solution { + /** + * @param {number[][]} grid + * @return {number} + */ + countServers(grid) { + let res = 0; + const ROWS = grid.length, COLS = grid[0].length; + + // Rows + for (let r = 0; r < ROWS; r++) { + let rowSum = grid[r].reduce((a, b) => a + b, 0); + if (rowSum <= 1) continue; + res += rowSum; + for (let c = 0; c < COLS; c++) { + if (grid[r][c] === 1) grid[r][c] = -1; // Mark + } + } + + // Cols + for (let c = 0; c < COLS; c++) { + let colSum = 0, unmarked = 0; + for (let r = 0; r < ROWS; r++) { + colSum += Math.abs(grid[r][c]); + if (grid[r][c] > 0) unmarked++; + else if (grid[r][c] < 0) grid[r][c] = 1; // Unmark + } + if (colSum >= 2) res += unmarked; + } + + return res; + } +} +``` + +```csharp +public class Solution { + public int CountServers(int[][] grid) { + int res = 0; + int ROWS = grid.Length, COLS = grid[0].Length; + + // Rows + for (int r = 0; r < ROWS; r++) { + int rowSum = 0; + for (int c = 0; c < COLS; c++) { + rowSum += grid[r][c]; + } + if (rowSum <= 1) continue; + res += rowSum; + for (int c = 0; c < COLS; c++) { + if (grid[r][c] == 1) grid[r][c] = -1; // Mark + } + } + + // Cols + for (int c = 0; c < COLS; c++) { + int colSum = 0, unmarked = 0; + for (int r = 0; r < ROWS; r++) { + colSum += Math.Abs(grid[r][c]); + if (grid[r][c] > 0) unmarked++; + else if (grid[r][c] < 0) grid[r][c] = 1; // Unmark + } + if (colSum >= 2) res += unmarked; + } + + return res; + } +} +``` + +::tabs-end + +### Time & Space Complexity + +* Time complexity: $O(m * n)$ +* Space complexity: $O(1)$ + +> Where $m$ is the number of rows and $n$ is the number of columns of the given matrix $grid$. \ No newline at end of file diff --git a/articles/counting-words-with-a-given-prefix.md b/articles/counting-words-with-a-given-prefix.md new file mode 100644 index 000000000..eb523a5e2 --- /dev/null +++ b/articles/counting-words-with-a-given-prefix.md @@ -0,0 +1,482 @@ +## 1. Brute Force + +::tabs-start + +```python +class Solution: + def prefixCount(self, words: List[str], pref: str) -> int: + N, res = len(pref), 0 + + for w in words: + if len(w) < len(pref): + continue + inc = 1 + for i in range(N): + if w[i] != pref[i]: + inc = 0 + break + res += inc + + return res +``` + +```java +public class Solution { + public int prefixCount(String[] words, String pref) { + int N = pref.length(), res = 0; + + for (String w : words) { + if (w.length() < N) continue; + int inc = 1; + for (int i = 0; i < N; i++) { + if (w.charAt(i) != pref.charAt(i)) { + inc = 0; + break; + } + } + res += inc; + } + + return res; + } +} +``` + +```cpp +class Solution { +public: + int prefixCount(vector& words, string pref) { + int N = pref.size(), res = 0; + + for (auto &w : words) { + if ((int)w.size() < N) continue; + int inc = 1; + for (int i = 0; i < N; i++) { + if (w[i] != pref[i]) { + inc = 0; + break; + } + } + res += inc; + } + + return res; + } +}; +``` + +```javascript +class Solution { + /** + * @param {string[]} words + * @param {string} pref + * @return {number} + */ + prefixCount(words, pref) { + let N = pref.length, res = 0; + + for (let w of words) { + if (w.length < N) continue; + let inc = 1; + for (let i = 0; i < N; i++) { + if (w[i] !== pref[i]) { + inc = 0; + break; + } + } + res += inc; + } + + return res; + } +} +``` + +```csharp +public class Solution { + public int PrefixCount(string[] words, string pref) { + int N = pref.Length, res = 0; + + foreach (string w in words) { + if (w.Length < N) continue; + int inc = 1; + for (int i = 0; i < N; i++) { + if (w[i] != pref[i]) { + inc = 0; + break; + } + } + res += inc; + } + + return res; + } +} +``` + +::tabs-end + +### Time & Space Complexity + +* Time complexity: $O(m * n)$ +* Space complexity: $O(1)$ + +> Where $m$ is the number of words and $n$ is the length of the string $pref$. + +--- + +## 2. Built-In Method + +::tabs-start + +```python +class Solution: + def prefixCount(self, words: List[str], pref: str) -> int: + res = 0 + for w in words: + res += w.startswith(pref) + return res +``` + +```java +public class Solution { + public int prefixCount(String[] words, String pref) { + int res = 0; + for (String w : words) { + if (w.startsWith(pref)) { + res++; + } + } + return res; + } +} +``` + +```cpp +class Solution { +public: + int prefixCount(vector& words, string pref) { + int res = 0; + for (string& w : words) { + if (w.rfind(pref, 0) == 0) { + res++; + } + } + return res; + } +}; +``` + +```javascript +class Solution { + /** + * @param {string[]} words + * @param {string} pref + * @return {number} + */ + prefixCount(words, pref) { + let res = 0; + for (let w of words) { + if (w.startsWith(pref)) { + res++; + } + } + return res; + } +} +``` + +```csharp +public class Solution { + public int PrefixCount(string[] words, string pref) { + int res = 0; + foreach (string w in words) { + if (w.StartsWith(pref)) { + res++; + } + } + return res; + } +} +``` + +::tabs-end + +### Time & Space Complexity + +* Time complexity: $O(m * n)$ +* Space complexity: $O(1)$ + +> Where $m$ is the number of words and $n$ is the length of the string $pref$. + +--- + +## 3. Trie + +::tabs-start + +```python +class PrefixNode: + def __init__(self): + self.children = {} # a -> PrefixNode + self.count = 0 + +class PrefixTree: + def __init__(self): + self.root = PrefixNode() + + def add(self, w: str, length: int) -> None: + cur = self.root + for i in range(length): + if w[i] not in cur.children: + cur.children[w[i]] = PrefixNode() + cur = cur.children[w[i]] + cur.count += 1 + + def count(self, pref: str) -> int: + cur = self.root + for c in pref: + if c not in cur.children: + return 0 + cur = cur.children[c] + return cur.count + +class Solution: + def prefixCount(self, words: List[str], pref: str) -> int: + prefix_tree = PrefixTree() + + for w in words: + if len(w) >= len(pref): + prefix_tree.add(w, len(pref)) + + return prefix_tree.count(pref) +``` + +```java +class PrefixNode { + PrefixNode[] children; + int count; + + public PrefixNode() { + children = new PrefixNode[26]; + count = 0; + } +} + +class PrefixTree { + PrefixNode root; + + public PrefixTree() { + root = new PrefixNode(); + } + + public void add(String w, int length) { + PrefixNode cur = root; + for (int i = 0; i < length; i++) { + int idx = w.charAt(i) - 'a'; + if (cur.children[idx] == null) { + cur.children[idx] = new PrefixNode(); + } + cur = cur.children[idx]; + cur.count++; + } + } + + public int count(String pref) { + PrefixNode cur = root; + for (int i = 0; i < pref.length(); i++) { + int idx = pref.charAt(i) - 'a'; + if (cur.children[idx] == null) { + return 0; + } + cur = cur.children[idx]; + } + return cur.count; + } +} + +public class Solution { + public int prefixCount(String[] words, String pref) { + PrefixTree prefixTree = new PrefixTree(); + + for (String w : words) { + if (w.length() >= pref.length()) { + prefixTree.add(w, pref.length()); + } + } + + return prefixTree.count(pref); + } +} +``` + +```cpp +struct PrefixNode { + PrefixNode* children[26]; + int count; + PrefixNode() { + for (int i = 0; i < 26; i++) children[i] = nullptr; + count = 0; + } +}; + +class PrefixTree { +public: + PrefixNode* root; + PrefixTree() { + root = new PrefixNode(); + } + + void add(const string& w, int length) { + PrefixNode* cur = root; + for (int i = 0; i < length; i++) { + int idx = w[i] - 'a'; + if (!cur->children[idx]) { + cur->children[idx] = new PrefixNode(); + } + cur = cur->children[idx]; + cur->count++; + } + } + + int count(const string& pref) { + PrefixNode* cur = root; + for (char c : pref) { + int idx = c - 'a'; + if (!cur->children[idx]) return 0; + cur = cur->children[idx]; + } + return cur->count; + } +}; + +class Solution { +public: + int prefixCount(vector& words, string pref) { + PrefixTree prefixTree; + for (string& w : words) { + if ((int)w.size() >= (int)pref.size()) { + prefixTree.add(w, pref.size()); + } + } + return prefixTree.count(pref); + } +}; +``` + +```javascript +class PrefixNode { + constructor() { + this.children = new Map(); + this.count = 0; + } +} + +class PrefixTree { + constructor() { + this.root = new PrefixNode(); + } + + add(w, length) { + let cur = this.root; + for (let i = 0; i < length; i++) { + if (!cur.children.has(w[i])) { + cur.children.set(w[i], new PrefixNode()); + } + cur = cur.children.get(w[i]); + cur.count++; + } + } + + count(pref) { + let cur = this.root; + for (let c of pref) { + if (!cur.children.has(c)) { + return 0; + } + cur = cur.children.get(c); + } + return cur.count; + } +} + +class Solution { + /** + * @param {string[]} words + * @param {string} pref + * @return {number} + */ + prefixCount(words, pref) { + let prefix_tree = new PrefixTree(); + for (let w of words) { + if (w.length >= pref.length) { + prefix_tree.add(w, pref.length); + } + } + return prefix_tree.count(pref); + } +} +``` + +```csharp +public class PrefixNode { + public PrefixNode[] children; + public int count; + + public PrefixNode() { + children = new PrefixNode[26]; + count = 0; + } +} + +public class PrefixTree { + private PrefixNode root; + + public PrefixTree() { + root = new PrefixNode(); + } + + public void Add(string w, int length) { + PrefixNode cur = root; + for (int i = 0; i < length; i++) { + int idx = w[i] - 'a'; + if (cur.children[idx] == null) { + cur.children[idx] = new PrefixNode(); + } + cur = cur.children[idx]; + cur.count++; + } + } + + public int Count(string pref) { + PrefixNode cur = root; + foreach (char c in pref) { + int idx = c - 'a'; + if (cur.children[idx] == null) return 0; + cur = cur.children[idx]; + } + return cur.count; + } +} + +public class Solution { + public int PrefixCount(string[] words, string pref) { + PrefixTree prefixTree = new PrefixTree(); + foreach (string w in words) { + if (w.Length >= pref.Length) { + prefixTree.Add(w, pref.Length); + } + } + return prefixTree.Count(pref); + } +} +``` + +::tabs-end + +### Time & Space Complexity + +* Time complexity: $O(m * l + n)$ +* Space complexity: $O(m * l)$ + +> Where $m$ is the number of words, $n$ is the length of the string $pref$ and $l$ is the maximum length of a word. \ No newline at end of file diff --git a/articles/first-unique-character-in-a-string.md b/articles/first-unique-character-in-a-string.md index 7fbb67baa..e329b5c7e 100644 --- a/articles/first-unique-character-in-a-string.md +++ b/articles/first-unique-character-in-a-string.md @@ -80,6 +80,25 @@ class Solution { } ``` +```csharp +public class Solution { + public int FirstUniqChar(string s) { + for (int i = 0; i < s.Length; i++) { + bool flag = true; + for (int j = 0; j < s.Length; j++) { + if (i == j) continue; + if (s[i] == s[j]) { + flag = false; + break; + } + } + if (flag) return i; + } + return -1; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -165,6 +184,27 @@ class Solution { } ``` +```csharp +public class Solution { + public int FirstUniqChar(string s) { + Dictionary count = new Dictionary(); + foreach (char c in s) { + if (!count.ContainsKey(c)) { + count[c] = 0; + } + count[c]++; + } + + for (int i = 0; i < s.Length; i++) { + if (count[s[i]] == 1) { + return i; + } + } + return -1; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -275,6 +315,31 @@ class Solution { } ``` +```csharp +public class Solution { + public int FirstUniqChar(string s) { + int n = s.Length; + Dictionary count = new Dictionary(); + + for (int i = 0; i < n; i++) { + char c = s[i]; + if (!count.ContainsKey(c)) { + count[c] = i; + } else { + count[c] = n; + } + } + + int res = n; + foreach (var kvp in count) { + res = Math.Min(res, kvp.Value); + } + + return res == n ? -1 : res; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -357,6 +422,24 @@ class Solution { } ``` +```csharp +public class Solution { + public int FirstUniqChar(string s) { + int n = s.Length; + int res = n; + + for (char ch = 'a'; ch <= 'z'; ch++) { + int index = s.IndexOf(ch); + if (index != -1 && s.LastIndexOf(ch) == index) { + res = Math.Min(res, index); + } + } + + return res == n ? -1 : res; + } +} +``` + ::tabs-end ### Time & Space Complexity diff --git a/articles/insert-delete-getrandom-o1.md b/articles/insert-delete-getrandom-o1.md index caa9b8f0c..671fb92d4 100644 --- a/articles/insert-delete-getrandom-o1.md +++ b/articles/insert-delete-getrandom-o1.md @@ -139,6 +139,44 @@ class RandomizedSet { } ``` +```csharp +public class RandomizedSet { + private Dictionary numMap; + private int size; + private Random rand; + + public RandomizedSet() { + numMap = new Dictionary(); + size = 0; + rand = new Random(); + } + + public bool Insert(int val) { + if (numMap.ContainsKey(val)) { + return false; + } + numMap[val] = 1; + size++; + return true; + } + + public bool Remove(int val) { + if (!numMap.ContainsKey(val)) { + return false; + } + numMap.Remove(val); + size--; + return true; + } + + public int GetRandom() { + int idx = rand.Next(0, size); + var keys = numMap.Keys.ToList(); + return keys[idx]; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -292,6 +330,47 @@ class RandomizedSet { } ``` +```csharp +public class RandomizedSet { + private Dictionary numMap; + private List nums; + private Random rand; + + public RandomizedSet() { + numMap = new Dictionary(); + nums = new List(); + rand = new Random(); + } + + public bool Insert(int val) { + if (numMap.ContainsKey(val)) { + return false; + } + numMap[val] = nums.Count; + nums.Add(val); + return true; + } + + public bool Remove(int val) { + if (!numMap.ContainsKey(val)) { + return false; + } + int idx = numMap[val]; + int last = nums[nums.Count - 1]; + nums[idx] = last; + numMap[last] = idx; + nums.RemoveAt(nums.Count - 1); + numMap.Remove(val); + return true; + } + + public int GetRandom() { + int index = rand.Next(nums.Count); + return nums[index]; + } +} +``` + ::tabs-end ### Time & Space Complexity diff --git a/articles/isomorphic-strings.md b/articles/isomorphic-strings.md index b65759396..fb831aa49 100644 --- a/articles/isomorphic-strings.md +++ b/articles/isomorphic-strings.md @@ -87,6 +87,25 @@ class Solution { } ``` +```csharp +public class Solution { + private bool Helper(string s, string t) { + Dictionary mp = new Dictionary(); + for (int i = 0; i < s.Length; i++) { + if (mp.ContainsKey(s[i]) && mp[s[i]] != t[i]) { + return false; + } + mp[s[i]] = t[i]; + } + return true; + } + + public bool IsIsomorphic(string s, string t) { + return Helper(s, t) && Helper(t, s); + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -173,6 +192,7 @@ class Solution { */ isIsomorphic(s, t) { const mapTS = new Map(); + const mapST = new Map(); for (let i = 0; i < s.length; i++) { const c1 = s[i], @@ -194,6 +214,29 @@ class Solution { } ``` +```csharp +public class Solution { + public bool IsIsomorphic(string s, string t) { + Dictionary mapST = new Dictionary(); + Dictionary mapTS = new Dictionary(); + + for (int i = 0; i < s.Length; i++) { + char c1 = s[i], c2 = t[i]; + + if ((mapST.ContainsKey(c1) && mapST[c1] != c2) || + (mapTS.ContainsKey(c2) && mapTS[c2] != c1)) { + return false; + } + + mapST[c1] = c2; + mapTS[c2] = c1; + } + + return true; + } +} +``` + ::tabs-end ### Time & Space Complexity diff --git a/articles/paint-house.md b/articles/paint-house.md index 9960e4492..8fc125f6f 100644 --- a/articles/paint-house.md +++ b/articles/paint-house.md @@ -4,7 +4,7 @@ ```python class Solution: - def min_cost(self, costs: List[List[int]]) -> int: + def minCost(self, costs: List[List[int]]) -> int: n = len(costs) def dfs(i, prevColor): @@ -104,6 +104,30 @@ class Solution { } ``` +```csharp +public class Solution { + int[][] costs; + int n; + + public int MinCost(int[][] costs) { + this.costs = costs; + n = costs.Length; + return Dfs(0, -1); + } + + private int Dfs(int i, int prevColor) { + if (i == n) return 0; + + int res = int.MaxValue; + for (int c = 0; c < 3; c++) { + if (c == prevColor) continue; + res = Math.Min(res, costs[i][c] + Dfs(i + 1, c)); + } + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -242,6 +266,39 @@ class Solution { } ``` +```csharp +public class Solution { + int[][] costs; + int[][] dp; + int n; + + public int MinCost(int[][] costs) { + this.costs = costs; + n = costs.Length; + dp = new int[n][]; + for (int i = 0; i < n; i++) { + dp[i] = new int[4]; + for (int j = 0; j < 4; j++) dp[i][j] = -1; + } + return Dfs(0, -1); + } + + private int Dfs(int i, int prevColor) { + if (i == n) return 0; + if (dp[i][prevColor + 1] != -1) return dp[i][prevColor + 1]; + + int res = int.MaxValue; + for (int c = 0; c < 3; c++) { + if (c == prevColor) continue; + res = Math.Min(res, costs[i][c] + Dfs(i + 1, c)); + } + + dp[i][prevColor + 1] = res; + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -351,6 +408,32 @@ class Solution { } ``` +```csharp +public class Solution { + public int MinCost(int[][] costs) { + int n = costs.Length; + if (n == 0) return 0; + + int[][] dp = new int[n][]; + for (int i = 0; i < n; i++) { + dp[i] = new int[3]; + } + + for (int c = 0; c < 3; c++) { + dp[0][c] = costs[0][c]; + } + + for (int i = 1; i < n; i++) { + for (int c = 0; c < 3; c++) { + dp[i][c] = costs[i][c] + Math.Min(dp[i - 1][(c + 1) % 3], dp[i - 1][(c + 2) % 3]); + } + } + + return Math.Min(dp[n - 1][0], Math.Min(dp[n - 1][1], dp[n - 1][2])); + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -438,6 +521,23 @@ class Solution { } ``` +```csharp +public class Solution { + public int MinCost(int[][] costs) { + int[] dp = new int[3]; + + for (int i = 0; i < costs.Length; i++) { + int dp0 = costs[i][0] + Math.Min(dp[1], dp[2]); + int dp1 = costs[i][1] + Math.Min(dp[0], dp[2]); + int dp2 = costs[i][2] + Math.Min(dp[0], dp[1]); + dp = new int[] { dp0, dp1, dp2 }; + } + + return Math.Min(dp[0], Math.Min(dp[1], dp[2])); + } +} +``` + ::tabs-end ### Time & Space Complexity diff --git a/articles/path-with-maximum-probability.md b/articles/path-with-maximum-probability.md index 1ab0f16e8..9eb34a9d8 100644 --- a/articles/path-with-maximum-probability.md +++ b/articles/path-with-maximum-probability.md @@ -133,12 +133,12 @@ class Solution { adj.get(dst).push([src, succProb[i]]); } - let pq = new MaxPriorityQueue({ priority: (x) => x[0] }); + let pq = new MaxPriorityQueue(x => x[0]); pq.enqueue([1.0, start_node]); let visited = new Set(); while (!pq.isEmpty()) { - let [prob, cur] = pq.dequeue().element; + let [prob, cur] = pq.dequeue(); visited.add(cur); if (cur === end_node) return prob; @@ -155,6 +155,56 @@ class Solution { } ``` +```csharp +public class Solution { + public double MaxProbability(int n, int[][] edges, double[] succProb, int start_node, int end_node) { + List[] adj = new List[n]; + for (int i = 0; i < n; i++) adj[i] = new List(); + + for (int i = 0; i < edges.Length; i++) { + int src = edges[i][0], dst = edges[i][1]; + adj[src].Add(new Pair(dst, succProb[i])); + adj[dst].Add(new Pair(src, succProb[i])); + } + + double[] maxProb = new double[n]; + maxProb[start_node] = 1.0; + + var pq = new PriorityQueue(); + pq.Enqueue(new Pair(start_node, 1.0), -1.0); // negative to simulate max-heap + + while (pq.Count > 0) { + var top = pq.Dequeue(); + int node = top.Node; + double currProb = top.Prob; + + if (node == end_node) return currProb; + if (currProb < maxProb[node]) continue; + + foreach (var nei in adj[node]) { + double newProb = currProb * nei.Prob; + if (newProb > maxProb[nei.Node]) { + maxProb[nei.Node] = newProb; + pq.Enqueue(new Pair(nei.Node, newProb), -newProb); + } + } + } + + return 0.0; + } + + public class Pair { + public int Node { get; } + public double Prob { get; } + + public Pair(int node, double prob) { + Node = node; + Prob = prob; + } + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -306,11 +356,11 @@ class Solution { let maxProb = Array(n).fill(0); maxProb[start_node] = 1.0; - let pq = new MaxPriorityQueue({ priority: (x) => x[1] }); + let pq = new MaxPriorityQueue(x => x[1]); pq.enqueue([start_node, 1.0]); while (!pq.isEmpty()) { - let [node, curr_prob] = pq.dequeue().element; + let [node, curr_prob] = pq.dequeue(); if (node === end_node) return curr_prob; if (curr_prob > maxProb[node]) continue; @@ -329,6 +379,58 @@ class Solution { } ``` +```csharp +public class Solution { + public double MaxProbability(int n, int[][] edges, double[] succProb, int start_node, int end_node) { + List[] adj = new List[n]; + for (int i = 0; i < n; i++) { + adj[i] = new List(); + } + + for (int i = 0; i < edges.Length; i++) { + int src = edges[i][0], dst = edges[i][1]; + adj[src].Add(new Pair(dst, succProb[i])); + adj[dst].Add(new Pair(src, succProb[i])); + } + + double[] maxProb = new double[n]; + maxProb[start_node] = 1.0; + + var pq = new PriorityQueue(); + pq.Enqueue(new Pair(start_node, 1.0), -1.0); + + while (pq.Count > 0) { + var top = pq.Dequeue(); + int node = top.Node; + double currProb = top.Prob; + + if (node == end_node) return currProb; + if (currProb < maxProb[node]) continue; + + foreach (var nei in adj[node]) { + double newProb = currProb * nei.Prob; + if (newProb > maxProb[nei.Node]) { + maxProb[nei.Node] = newProb; + pq.Enqueue(new Pair(nei.Node, newProb), -newProb); + } + } + } + + return 0.0; + } + + public class Pair { + public int Node { get; } + public double Prob { get; } + + public Pair(int node, double prob) { + Node = node; + Prob = prob; + } + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -464,6 +566,35 @@ class Solution { } ``` +```csharp +public class Solution { + public double MaxProbability(int n, int[][] edges, double[] succProb, int start_node, int end_node) { + double[] maxProb = new double[n]; + maxProb[start_node] = 1.0; + + for (int i = 0; i < n; i++) { + bool updated = false; + for (int j = 0; j < edges.Length; j++) { + int src = edges[j][0], dst = edges[j][1]; + + if (maxProb[src] * succProb[j] > maxProb[dst]) { + maxProb[dst] = maxProb[src] * succProb[j]; + updated = true; + } + + if (maxProb[dst] * succProb[j] > maxProb[src]) { + maxProb[src] = maxProb[dst] * succProb[j]; + updated = true; + } + } + if (!updated) break; + } + + return maxProb[end_node]; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -622,6 +753,50 @@ class Solution { } ``` +```csharp +public class Solution { + public double MaxProbability(int n, int[][] edges, double[] succProb, int start_node, int end_node) { + List[] adj = new List[n]; + for (int i = 0; i < n; i++) adj[i] = new List(); + + for (int i = 0; i < edges.Length; i++) { + int src = edges[i][0], dst = edges[i][1]; + adj[src].Add(new Pair(dst, succProb[i])); + adj[dst].Add(new Pair(src, succProb[i])); + } + + double[] maxProb = new double[n]; + maxProb[start_node] = 1.0; + Queue q = new Queue(); + q.Enqueue(start_node); + + while (q.Count > 0) { + int node = q.Dequeue(); + + foreach (Pair nei in adj[node]) { + double newProb = maxProb[node] * nei.prob; + if (newProb > maxProb[nei.node]) { + maxProb[nei.node] = newProb; + q.Enqueue(nei.node); + } + } + } + + return maxProb[end_node]; + } + + public class Pair { + public int node; + public double prob; + + public Pair(int node, double prob) { + this.node = node; + this.prob = prob; + } + } +} +``` + ::tabs-end ### Time & Space Complexity diff --git a/articles/power-of-two.md b/articles/power-of-two.md index 97b809d7d..bd6bc1567 100644 --- a/articles/power-of-two.md +++ b/articles/power-of-two.md @@ -61,6 +61,22 @@ class Solution { } ``` +```csharp +public class Solution { + public bool IsPowerOfTwo(int n) { + if (n <= 0) { + return false; + } + + int x = 1; + while (x < n) { + x *= 2; + } + return x == n; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -131,6 +147,20 @@ class Solution { } ``` +```csharp +public class Solution { + public bool IsPowerOfTwo(int n) { + if (n == 1) { + return true; + } + if (n <= 0 || n % 2 == 1) { + return false; + } + return IsPowerOfTwo(n / 2); + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -199,6 +229,20 @@ class Solution { } ``` +```csharp +public class Solution { + public bool IsPowerOfTwo(int n) { + if (n <= 0) { + return false; + } + while (n % 2 == 0) { + n >>= 1; + } + return n == 1; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -247,6 +291,14 @@ class Solution { } ``` +```csharp +public class Solution { + public bool IsPowerOfTwo(int n) { + return n > 0 && (n & -n) == n; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -295,6 +347,14 @@ class Solution { } ``` +```csharp +public class Solution { + public bool IsPowerOfTwo(int n) { + return n > 0 && (n & (n - 1)) == 0; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -343,6 +403,14 @@ class Solution { } ``` +```csharp +public class Solution { + public bool IsPowerOfTwo(int n) { + return n > 0 && ((1 << 30) % n) == 0; + } +} +``` + ::tabs-end ### Time & Space Complexity diff --git a/articles/remove-sub-folders-from-the-filesystem.md b/articles/remove-sub-folders-from-the-filesystem.md new file mode 100644 index 000000000..248431eed --- /dev/null +++ b/articles/remove-sub-folders-from-the-filesystem.md @@ -0,0 +1,497 @@ +## 1. Hash Set + +::tabs-start + +```python +class Solution: + def removeSubfolders(self, folder: List[str]) -> List[str]: + res = [] + folder_set = set(folder) + + for f in folder: + res.append(f) + for i in range(len(f)): + if f[i] == "/" and f[:i] in folder_set: + res.pop() + break + + return res +``` + +```java +public class Solution { + public List removeSubfolders(String[] folder) { + List res = new ArrayList<>(); + Set folder_set = new HashSet<>(Arrays.asList(folder)); + + for (String f : folder) { + res.add(f); + for (int i = 0; i < f.length(); i++) { + if (f.charAt(i) == '/' && folder_set.contains(f.substring(0, i))) { + res.remove(res.size() - 1); + break; + } + } + } + + return res; + } +} +``` + +```cpp +class Solution { +public: + vector removeSubfolders(vector& folder) { + vector res; + unordered_set folder_set(folder.begin(), folder.end()); + + for (string& f : folder) { + res.push_back(f); + for (int i = 0; i < f.size(); i++) { + if (f[i] == '/' && folder_set.count(f.substr(0, i))) { + res.pop_back(); + break; + } + } + } + + return res; + } +}; +``` + +```javascript +class Solution { + /** + * @param {string[]} folder + * @return {string[]} + */ + removeSubfolders(folder) { + let res = []; + let folder_set = new Set(folder); + + for (let f of folder) { + res.push(f); + for (let i = 0; i < f.length; i++) { + if (f[i] === '/' && folder_set.has(f.slice(0, i))) { + res.pop(); + break; + } + } + } + + return res; + } +} +``` + +```csharp +public class Solution { + public List RemoveSubfolders(string[] folder) { + List res = new List(); + HashSet folder_set = new HashSet(folder); + + foreach (string f in folder) { + res.Add(f); + for (int i = 0; i < f.Length; i++) { + if (f[i] == '/' && folder_set.Contains(f.Substring(0, i))) { + res.RemoveAt(res.Count - 1); + break; + } + } + } + + return res; + } +} +``` + +::tabs-end + +### Time & Space Complexity + +* Time complexity: $O(n * m ^ 2)$ +* Space complexity: $O(n * m)$ + +> Where $n$ is the size of the string array $folder$ and $m$ is the length of each string. + +--- + +## 2. Sorting + +::tabs-start + +```python +class Solution: + def removeSubfolders(self, folder: List[str]) -> List[str]: + folder.sort() + res = [folder[0]] + + for i in range(1, len(folder)): + if not folder[i].startswith(res[-1] + "/"): + res.append(folder[i]) + + return res +``` + +```java +public class Solution { + public List removeSubfolders(String[] folder) { + Arrays.sort(folder); + List res = new ArrayList<>(); + res.add(folder[0]); + + for (int i = 1; i < folder.length; i++) { + if (!folder[i].startsWith(res.get(res.size() - 1) + "/")) { + res.add(folder[i]); + } + } + + return res; + } +} +``` + +```cpp +class Solution { +public: + vector removeSubfolders(vector& folder) { + sort(folder.begin(), folder.end()); + vector res; + res.push_back(folder[0]); + + for (int i = 1; i < folder.size(); i++) { + if (folder[i].find(res.back() + "/") != 0) { + res.push_back(folder[i]); + } + } + + return res; + } +}; +``` + +```javascript +class Solution { + /** + * @param {string[]} folder + * @return {string[]} + */ + removeSubfolders(folder) { + folder.sort(); + let res = [folder[0]]; + + for (let i = 1; i < folder.length; i++) { + if (!folder[i].startsWith(res[res.length - 1] + "/")) { + res.push(folder[i]); + } + } + + return res; + } +} +``` + +```csharp +public class Solution { + public List RemoveSubfolders(string[] folder) { + Array.Sort(folder); + List res = new List(); + res.Add(folder[0]); + + for (int i = 1; i < folder.Length; i++) { + if (!folder[i].StartsWith(res[res.Count - 1] + "/")) { + res.Add(folder[i]); + } + } + + return res; + } +} +``` + +::tabs-end + +### Time & Space Complexity + +* Time complexity: $O(n * m ^ 2)$ +* Space complexity: $O(n * m)$ + +> Where $n$ is the size of the string array $folder$ and $m$ is the length of each string. + +--- + +## 3. Trie + +::tabs-start + +```python +class Trie: + def __init__(self): + self.children = {} # string -> Trie + self.end_of_folder = False + + def add(self, path: str) -> None: + cur = self + for f in path.split("/"): + if f not in cur.children: + cur.children[f] = Trie() + cur = cur.children[f] + cur.end_of_folder = True + + def prefix_search(self, path: str) -> bool: + cur = self + folders = path.split("/") + for i in range(len(folders) - 1): + cur = cur.children[folders[i]] + if cur.end_of_folder: + return True + return False + + +class Solution: + def removeSubfolders(self, folder: List[str]) -> List[str]: + trie = Trie() + for f in folder: + trie.add(f) + + res = [] + for f in folder: + if not trie.prefix_search(f): + res.append(f) + return res +``` + +```java +class Trie { + Trie[] children = new Trie[128]; + boolean end_of_folder = false; + + void add(String path) { + Trie cur = this; + for (String f : path.split("/")) { + if (f.isEmpty()) continue; + for (char c : f.toCharArray()) { + if (cur.children[c] == null) cur.children[c] = new Trie(); + cur = cur.children[c]; + } + if (cur.children['/'] == null) cur.children['/'] = new Trie(); + cur = cur.children['/']; + } + cur.end_of_folder = true; + } + + boolean prefixSearch(String path) { + Trie cur = this; + String[] folders = path.split("/"); + for (int i = 0; i < folders.length - 1; i++) { + if (folders[i].isEmpty()) continue; + for (char c : folders[i].toCharArray()) { + cur = cur.children[c]; + } + cur = cur.children['/']; + if (cur.end_of_folder) return true; + } + return false; + } +} + +public class Solution { + public List removeSubfolders(String[] folder) { + Trie trie = new Trie(); + for (String f : folder) trie.add(f); + + List res = new ArrayList<>(); + for (String f : folder) { + if (!trie.prefixSearch(f)) res.add(f); + } + return res; + } +} +``` + +```cpp +class Trie { +public: + Trie* children[128] = {}; + bool end_of_folder = false; + + void add(const string& path) { + Trie* cur = this; + string part; + for (int i = 0; i < path.size(); i++) { + if (path[i] == '/') { + if (!part.empty()) { + for (char c : part) { + if (!cur->children[(int)c]) cur->children[(int)c] = new Trie(); + cur = cur->children[(int)c]; + } + if (!cur->children[(int)'/']) cur->children[(int)'/'] = new Trie(); + cur = cur->children[(int)'/']; + part.clear(); + } + } else { + part += path[i]; + } + } + if (!part.empty()) { + for (char c : part) { + if (!cur->children[(int)c]) cur->children[(int)c] = new Trie(); + cur = cur->children[(int)c]; + } + if (!cur->children[(int)'/']) cur->children[(int)'/'] = new Trie(); + cur = cur->children[(int)'/']; + } + cur->end_of_folder = true; + } + + bool prefixSearch(const string& path) { + Trie* cur = this; + string part; + for (int i = 0; i < (int)path.size(); i++) { + if (path[i] == '/') { + if (!part.empty()) { + for (char c : part) cur = cur->children[(int)c]; + cur = cur->children[(int)'/']; + if (cur->end_of_folder) return true; + part.clear(); + } + } else { + part += path[i]; + } + } + return false; + } +}; + +class Solution { +public: + vector removeSubfolders(vector& folder) { + Trie trie; + for (auto& f : folder) trie.add(f); + vector res; + for (auto& f : folder) { + if (!trie.prefixSearch(f)) res.push_back(f); + } + return res; + } +}; +``` + +```javascript +class Trie { + constructor() { + this.children = new Array(128).fill(null); + this.end_of_folder = false; + } + + /** + * @param {string[]} path + * @return {void} + */ + add(path) { + let cur = this; + for (let f of path.split("/")) { + if (f === "") continue; + for (let c of f) { + if (!cur.children[c.charCodeAt(0)]) cur.children[c.charCodeAt(0)] = new Trie(); + cur = cur.children[c.charCodeAt(0)]; + } + if (!cur.children['/'.charCodeAt(0)]) cur.children['/'.charCodeAt(0)] = new Trie(); + cur = cur.children['/'.charCodeAt(0)]; + } + cur.end_of_folder = true; + } + + /** + * @param {string} path + * @return {boolean} + */ + prefixSearch(path) { + let cur = this; + let folders = path.split("/"); + for (let i = 0; i < folders.length - 1; i++) { + if (folders[i] === "") continue; + for (let c of folders[i]) { + cur = cur.children[c.charCodeAt(0)]; + } + cur = cur.children['/'.charCodeAt(0)]; + if (cur.end_of_folder) return true; + } + return false; + } +} + +class Solution { + /** + * @param {string[]} folder + * @return {string[]} + */ + removeSubfolders(folder) { + let trie = new Trie(); + for (let f of folder) trie.add(f); + + let res = []; + for (let f of folder) { + if (!trie.prefixSearch(f)) res.push(f); + } + return res; + } +} +``` + +```csharp +public class Trie { + public Trie[] children = new Trie[128]; + public bool end_of_folder = false; + + public void Add(string path) { + Trie cur = this; + foreach (string f in path.Split('/')) { + if (f.Length == 0) continue; + foreach (char c in f) { + if (cur.children[c] == null) cur.children[c] = new Trie(); + cur = cur.children[c]; + } + if (cur.children['/'] == null) cur.children['/'] = new Trie(); + cur = cur.children['/']; + } + cur.end_of_folder = true; + } + + public bool PrefixSearch(string path) { + Trie cur = this; + string[] folders = path.Split('/'); + for (int i = 0; i < folders.Length - 1; i++) { + if (folders[i].Length == 0) continue; + foreach (char c in folders[i]) cur = cur.children[c]; + cur = cur.children['/']; + if (cur.end_of_folder) return true; + } + return false; + } +} + +public class Solution { + public List RemoveSubfolders(string[] folder) { + Trie trie = new Trie(); + foreach (string f in folder) trie.Add(f); + + List res = new List(); + foreach (string f in folder) { + if (!trie.PrefixSearch(f)) res.Add(f); + } + return res; + } +} +``` + +::tabs-end + +### Time & Space Complexity + +* Time complexity: $O(n * m)$ +* Space complexity: $O(n * m)$ + +> Where $n$ is the size of the string array $folder$ and $m$ is the length of each string. \ No newline at end of file diff --git a/articles/shortest-bridge.md b/articles/shortest-bridge.md index 11ea77be0..a0bddf399 100644 --- a/articles/shortest-bridge.md +++ b/articles/shortest-bridge.md @@ -257,6 +257,67 @@ class Solution { } ``` +```csharp +public class Solution { + public int ShortestBridge(int[][] grid) { + int N = grid.Length; + int[][] directions = new int[][] { + new int[] {0, 1}, new int[] {0, -1}, + new int[] {1, 0}, new int[] {-1, 0} + }; + + bool Invalid(int r, int c) { + return r < 0 || c < 0 || r == N || c == N; + } + + HashSet<(int, int)> visit = new HashSet<(int, int)>(); + + void Dfs(int r, int c) { + if (Invalid(r, c) || grid[r][c] == 0 || visit.Contains((r, c))) + return; + visit.Add((r, c)); + foreach (var d in directions) { + Dfs(r + d[0], c + d[1]); + } + } + + int Bfs() { + int res = 0; + Queue<(int, int)> q = new Queue<(int, int)>(visit); + + while (q.Count > 0) { + int size = q.Count; + for (int i = 0; i < size; i++) { + var (r, c) = q.Dequeue(); + foreach (var d in directions) { + int curR = r + d[0], curC = c + d[1]; + if (Invalid(curR, curC) || visit.Contains((curR, curC))) + continue; + if (grid[curR][curC] == 1) + return res; + q.Enqueue((curR, curC)); + visit.Add((curR, curC)); + } + } + res++; + } + return -1; + } + + for (int r = 0; r < N; r++) { + for (int c = 0; c < N; c++) { + if (grid[r][c] == 1) { + Dfs(r, c); + return Bfs(); + } + } + } + + return -1; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -477,6 +538,61 @@ class Solution { } ``` +```csharp +public class Solution { + public int ShortestBridge(int[][] grid) { + int N = grid.Length; + int[][] direct = new int[][] { + new int[] {0, 1}, new int[] {0, -1}, new int[] {1, 0}, new int[] {-1, 0} + }; + + Queue<(int, int)> q = new Queue<(int, int)>(); + + void Dfs(int r, int c) { + if (r >= 0 && r < N && c >= 0 && c < N && grid[r][c] == 1) { + grid[r][c] = 2; + q.Enqueue((r, c)); + foreach (var d in direct) { + Dfs(r + d[0], c + d[1]); + } + } + } + + for (int r = 0; r < N; r++) { + for (int c = 0; c < N; c++) { + if (grid[r][c] == 1) { + Dfs(r, c); + break; + } + } + if (q.Count > 0) break; + } + + int res = 0; + while (q.Count > 0) { + int size = q.Count; + for (int i = 0; i < size; i++) { + var (r, c) = q.Dequeue(); + foreach (var d in direct) { + int nr = r + d[0], nc = c + d[1]; + if (nr >= 0 && nr < N && nc >= 0 && nc < N) { + if (grid[nr][nc] == 1) { + return res; + } + if (grid[nr][nc] == 0) { + grid[nr][nc] = 2; + q.Enqueue((nr, nc)); + } + } + } + } + res++; + } + return -1; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -722,6 +838,70 @@ class Solution { } ``` +```csharp +public class Solution { + public int ShortestBridge(int[][] grid) { + int N = grid.Length; + int[][] directions = new int[][] { + new int[] {0, 1}, new int[] {0, -1}, new int[] {1, 0}, new int[] {-1, 0} + }; + + Queue<(int, int)> q2 = new Queue<(int, int)>(); + bool found = false; + + for (int r = 0; r < N; r++) { + if (found) break; + for (int c = 0; c < N; c++) { + if (grid[r][c] == 1) { + Queue<(int, int)> q1 = new Queue<(int, int)>(); + q1.Enqueue((r, c)); + grid[r][c] = 2; + + while (q1.Count > 0) { + var (x, y) = q1.Dequeue(); + q2.Enqueue((x, y)); + + foreach (var d in directions) { + int nx = x + d[0], ny = y + d[1]; + if (nx >= 0 && nx < N && ny >= 0 && ny < N && grid[nx][ny] == 1) { + grid[nx][ny] = 2; + q1.Enqueue((nx, ny)); + } + } + } + + found = true; + break; + } + } + } + + int res = 0; + while (q2.Count > 0) { + int size = q2.Count; + for (int i = 0; i < size; i++) { + var (x, y) = q2.Dequeue(); + foreach (var d in directions) { + int nx = x + d[0], ny = y + d[1]; + if (nx >= 0 && nx < N && ny >= 0 && ny < N) { + if (grid[nx][ny] == 1) { + return res; + } + if (grid[nx][ny] == 0) { + grid[nx][ny] = 2; + q2.Enqueue((nx, ny)); + } + } + } + } + res++; + } + + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -1111,6 +1291,68 @@ class Solution { } ``` +```csharp +public class Solution { + public int ShortestBridge(int[][] grid) { + int N = grid.Length; + int[][] direct = new int[][] { + new int[] {0, 1}, new int[] {0, -1}, new int[] {1, 0}, new int[] {-1, 0} + }; + Queue q2 = new Queue(); + + bool found = false; + for (int r = 0; r < N; r++) { + if (found) break; + for (int c = 0; c < N; c++) { + if (grid[r][c] == 1) { + Queue q1 = new Queue(); + q1.Enqueue(new int[] { r, c }); + grid[r][c] = 2; + + while (q1.Count > 0) { + int[] cell = q1.Dequeue(); + int x = cell[0], y = cell[1]; + q2.Enqueue(new int[] { x, y }); + + foreach (var d in direct) { + int nx = x + d[0], ny = y + d[1]; + if (nx >= 0 && ny >= 0 && nx < N && ny < N && grid[nx][ny] == 1) { + grid[nx][ny] = 2; + q1.Enqueue(new int[] { nx, ny }); + } + } + } + found = true; + break; + } + } + } + + int res = 0; + while (q2.Count > 0) { + int size = q2.Count; + for (int i = 0; i < size; i++) { + int[] cell = q2.Dequeue(); + int x = cell[0], y = cell[1]; + + foreach (var d in direct) { + int nx = x + d[0], ny = y + d[1]; + if (nx >= 0 && ny >= 0 && nx < N && ny < N) { + if (grid[nx][ny] == 1) return res; + if (grid[nx][ny] == 0) { + grid[nx][ny] = 2; + q2.Enqueue(new int[] { nx, ny }); + } + } + } + } + res++; + } + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity diff --git a/articles/sort-array-by-parity.md b/articles/sort-array-by-parity.md index 51437ff50..6d550fa30 100644 --- a/articles/sort-array-by-parity.md +++ b/articles/sort-array-by-parity.md @@ -43,6 +43,15 @@ class Solution { } ``` +```csharp +public class Solution { + public int[] SortArrayByParity(int[] nums) { + Array.Sort(nums, (a, b) => (a & 1).CompareTo(b & 1)); + return nums; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -161,6 +170,33 @@ class Solution { } ``` +```csharp +public class Solution { + public int[] SortArrayByParity(int[] nums) { + List even = new List(); + List odd = new List(); + + foreach (int num in nums) { + if ((num & 1) == 1) { + odd.Add(num); + } else { + even.Add(num); + } + } + + int idx = 0; + foreach (int e in even) { + nums[idx++] = e; + } + foreach (int o in odd) { + nums[idx++] = o; + } + + return nums; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -245,6 +281,25 @@ class Solution { } ``` +```csharp +public class Solution { + public int[] SortArrayByParity(int[] nums) { + int i = 0, j = nums.Length - 1; + while (i < j) { + if ((nums[i] & 1) == 1) { + int temp = nums[i]; + nums[i] = nums[j]; + nums[j] = temp; + j--; + } else { + i++; + } + } + return nums; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -318,6 +373,23 @@ class Solution { } ``` +```csharp +public class Solution { + public int[] SortArrayByParity(int[] nums) { + int l = 0; + for (int r = 0; r < nums.Length; r++) { + if (nums[r] % 2 == 0) { + int temp = nums[l]; + nums[l] = nums[r]; + nums[r] = temp; + l++; + } + } + return nums; + } +} +``` + ::tabs-end ### Time & Space Complexity diff --git a/articles/subarray-product-less-than-k.md b/articles/subarray-product-less-than-k.md index b1d660234..d5778d40a 100644 --- a/articles/subarray-product-less-than-k.md +++ b/articles/subarray-product-less-than-k.md @@ -82,6 +82,25 @@ class Solution { } ``` +```csharp +public class Solution { + public int NumSubarrayProductLessThanK(int[] nums, int k) { + int n = nums.Length, res = 0; + + for (int i = 0; i < n; i++) { + long curProd = 1; + for (int j = i; j < n; j++) { + curProd *= nums[j]; + if (curProd >= k) break; + res++; + } + } + + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity @@ -112,11 +131,10 @@ class Solution: l, r = i + 1, n + 1 while l < r: mid = (l + r) >> 1 - if logs[mid] < logs[i] + logK: + if logs[mid] < logs[i] + logK - 1e-9: l = mid + 1 else: r = mid - res += l - (i + 1) return res @@ -126,20 +144,18 @@ class Solution: public class Solution { public int numSubarrayProductLessThanK(int[] nums, int k) { if (k <= 1) return 0; - - int n = nums.length, res = 0; + int n = nums.length; double[] logs = new double[n + 1]; double logK = Math.log(k); - for (int i = 0; i < n; i++) { logs[i + 1] = logs[i] + Math.log(nums[i]); } - + int res = 0; for (int i = 0; i < n; i++) { int l = i + 1, r = n + 1; while (l < r) { - int mid = (l + r) / 2; - if (logs[mid] < logs[i] + logK) { + int mid = (l + r) >> 1; + if (logs[mid] < logs[i] + logK - 1e-12) { l = mid + 1; } else { r = mid; @@ -147,7 +163,6 @@ public class Solution { } res += l - (i + 1); } - return res; } } @@ -158,20 +173,18 @@ class Solution { public: int numSubarrayProductLessThanK(vector& nums, int k) { if (k <= 1) return 0; - - int n = nums.size(), res = 0; - vector logs(n + 1, 0); + int n = nums.size(); + vector logs(n + 1, 0.0); double logK = log(k); - for (int i = 0; i < n; i++) { logs[i + 1] = logs[i] + log(nums[i]); } - + int res = 0; for (int i = 0; i < n; i++) { int l = i + 1, r = n + 1; while (l < r) { - int mid = (l + r) / 2; - if (logs[mid] < logs[i] + logK) { + int mid = (l + r) >> 1; + if (logs[mid] < logs[i] + logK - 1e-12) { l = mid + 1; } else { r = mid; @@ -179,7 +192,6 @@ public: } res += l - (i + 1); } - return res; } }; @@ -194,22 +206,18 @@ class Solution { */ numSubarrayProductLessThanK(nums, k) { if (k <= 1) return 0; - const n = nums.length; - let res = 0; const logs = new Array(n + 1).fill(0); const logK = Math.log(k); - for (let i = 0; i < n; i++) { logs[i + 1] = logs[i] + Math.log(nums[i]); } - + let res = 0; for (let i = 0; i < n; i++) { - let l = i + 1, - r = n + 1; + let l = i + 1, r = n + 1; while (l < r) { - const mid = Math.floor((l + r) / 2); - if (logs[mid] < logs[i] + logK) { + let mid = (l + r) >> 1; + if (logs[mid] < logs[i] + logK - 1e-12) { l = mid + 1; } else { r = mid; @@ -217,7 +225,34 @@ class Solution { } res += l - (i + 1); } + return res; + } +} +``` +```csharp +public class Solution { + public int NumSubarrayProductLessThanK(int[] nums, int k) { + if (k <= 1) return 0; + int n = nums.Length; + double[] logs = new double[n + 1]; + double logK = Math.Log(k); + for (int i = 0; i < n; i++) { + logs[i + 1] = logs[i] + Math.Log(nums[i]); + } + int res = 0; + for (int i = 0; i < n; i++) { + int l = i + 1, r = n + 1; + while (l < r) { + int mid = (l + r) >> 1; + if (logs[mid] < logs[i] + logK - 1e-12) { + l = mid + 1; + } else { + r = mid; + } + } + res += l - (i + 1); + } return res; } } @@ -309,9 +344,28 @@ class Solution { } ``` +```csharp +public class Solution { + public int NumSubarrayProductLessThanK(int[] nums, int k) { + int res = 0; + int l = 0; + long product = 1; + for (int r = 0; r < nums.Length; r++) { + product *= nums[r]; + while (l <= r && product >= k) { + product /= nums[l]; + l++; + } + res += (r - l + 1); + } + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity - Time complexity: $O(n)$ -- Space complexity: $O(1)$ +- Space complexity: $O(1)$ \ No newline at end of file diff --git a/articles/text-justification.md b/articles/text-justification.md index 6b20d676a..d41022128 100644 --- a/articles/text-justification.md +++ b/articles/text-justification.md @@ -175,6 +175,49 @@ class Solution { } ``` +```csharp +public class Solution { + public List FullJustify(string[] words, int maxWidth) { + List res = new List(); + List line = new List(); + int length = 0, i = 0; + + while (i < words.Length) { + // If the current word can fit in the line + if (length + words[i].Length + line.Count <= maxWidth) { + line.Add(words[i]); + length += words[i].Length; + i++; + } else { + // Line complete + int extra_space = maxWidth - length; + int space = extra_space / Math.Max(1, line.Count - 1); + int remainder = extra_space % Math.Max(1, line.Count - 1); + + for (int j = 0; j < Math.Max(1, line.Count - 1); j++) { + line[j] += new string(' ', space); + if (remainder > 0) { + line[j] += " "; + remainder--; + } + } + + res.Add(string.Join("", line)); + line.Clear(); + length = 0; + } + } + + // Handling last line + string last_line = string.Join(" ", line); + int trail_space = maxWidth - last_line.Length; + res.Add(last_line + new string(' ', trail_space)); + + return res; + } +} +``` + ::tabs-end ### Time & Space Complexity