+
+int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
+ int capacity = 1;
+ while (capacity < numsSize * 2) capacity <<= 1;
+ int* keys = malloc(capacity * sizeof(int));
+ int* vals = malloc(capacity * sizeof(int));
+ char* used = calloc(capacity, sizeof(char));
+ if (!keys || !vals || !used) {
+ free(keys);
+ free(vals);
+ free(used);
+ *returnSize = 0;
+ return NULL;
+ }
+ for (int i = 0; i < numsSize; ++i) {
+ int x = nums[i];
+ int y = target - x;
+ unsigned int h = (unsigned int) y & (capacity - 1);
+ while (used[h]) {
+ if (keys[h] == y) {
+ int* res = malloc(2 * sizeof(int));
+ res[0] = vals[h];
+ res[1] = i;
+ *returnSize = 2;
+ free(keys);
+ free(vals);
+ free(used);
+ return res;
+ }
+ h = (h + 1) & (capacity - 1);
+ }
+ unsigned int h2 = (unsigned int) x & (capacity - 1);
+ while (used[h2]) h2 = (h2 + 1) & (capacity - 1);
+ used[h2] = 1;
+ keys[h2] = x;
+ vals[h2] = i;
+ }
+ *returnSize = 0;
+ free(keys);
+ free(vals);
+ free(used);
+ return NULL;
+}
diff --git a/solution/0000-0099/0002.Add Two Numbers/README.md b/solution/0000-0099/0002.Add Two Numbers/README.md
index 3806f64b53d17..6cda4e7ca4018 100644
--- a/solution/0000-0099/0002.Add Two Numbers/README.md
+++ b/solution/0000-0099/0002.Add Two Numbers/README.md
@@ -147,9 +147,9 @@ class Solution {
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
- ListNode* dummy = new ListNode();
+ ListNode dummy;
int carry = 0;
- ListNode* cur = dummy;
+ ListNode* cur = &dummy;
while (l1 || l2 || carry) {
int s = (l1 ? l1->val : 0) + (l2 ? l2->val : 0) + carry;
carry = s / 10;
@@ -158,7 +158,7 @@ public:
l1 = l1 ? l1->next : nullptr;
l2 = l2 ? l2->next : nullptr;
}
- return dummy->next;
+ return dummy.next;
}
};
```
@@ -494,6 +494,52 @@ proc addTwoNumbers(l1: var SinglyLinkedList, l2: var SinglyLinkedList): SinglyLi
result = aggregate
```
+#### C
+
+```c
+
+/**
+ * Definition for singly-linked list.
+ * struct ListNode {
+ * int val;
+ * struct ListNode *next;
+ * };
+ */
+
+struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
+ struct ListNode* dummy = (struct ListNode*) malloc(sizeof(struct ListNode));
+ dummy->val = 0;
+ dummy->next = NULL;
+ struct ListNode* curr = dummy;
+ int carry = 0;
+
+ while (l1 != NULL || l2 != NULL || carry != 0) {
+ int sum = carry;
+ if (l1 != NULL) {
+ sum += l1->val;
+ l1 = l1->next;
+ }
+ if (l2 != NULL) {
+ sum += l2->val;
+ l2 = l2->next;
+ }
+
+ carry = sum / 10;
+ int val = sum % 10;
+
+ struct ListNode* newNode = (struct ListNode*) malloc(sizeof(struct ListNode));
+ newNode->val = val;
+ newNode->next = NULL;
+ curr->next = newNode;
+ curr = curr->next;
+ }
+
+ struct ListNode* result = dummy->next;
+ free(dummy);
+ return result;
+}
+```
+
diff --git a/solution/0000-0099/0002.Add Two Numbers/README_EN.md b/solution/0000-0099/0002.Add Two Numbers/README_EN.md
index f6878f0937322..99c96e3961490 100644
--- a/solution/0000-0099/0002.Add Two Numbers/README_EN.md
+++ b/solution/0000-0099/0002.Add Two Numbers/README_EN.md
@@ -143,9 +143,9 @@ class Solution {
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
- ListNode* dummy = new ListNode();
+ ListNode dummy;
int carry = 0;
- ListNode* cur = dummy;
+ ListNode* cur = &dummy;
while (l1 || l2 || carry) {
int s = (l1 ? l1->val : 0) + (l2 ? l2->val : 0) + carry;
carry = s / 10;
@@ -154,7 +154,7 @@ public:
l1 = l1 ? l1->next : nullptr;
l2 = l2 ? l2->next : nullptr;
}
- return dummy->next;
+ return dummy.next;
}
};
```
@@ -490,6 +490,52 @@ proc addTwoNumbers(l1: var SinglyLinkedList, l2: var SinglyLinkedList): SinglyLi
result = aggregate
```
+#### C
+
+```c
+
+/**
+ * Definition for singly-linked list.
+ * struct ListNode {
+ * int val;
+ * struct ListNode *next;
+ * };
+ */
+
+struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
+ struct ListNode* dummy = (struct ListNode*) malloc(sizeof(struct ListNode));
+ dummy->val = 0;
+ dummy->next = NULL;
+ struct ListNode* curr = dummy;
+ int carry = 0;
+
+ while (l1 != NULL || l2 != NULL || carry != 0) {
+ int sum = carry;
+ if (l1 != NULL) {
+ sum += l1->val;
+ l1 = l1->next;
+ }
+ if (l2 != NULL) {
+ sum += l2->val;
+ l2 = l2->next;
+ }
+
+ carry = sum / 10;
+ int val = sum % 10;
+
+ struct ListNode* newNode = (struct ListNode*) malloc(sizeof(struct ListNode));
+ newNode->val = val;
+ newNode->next = NULL;
+ curr->next = newNode;
+ curr = curr->next;
+ }
+
+ struct ListNode* result = dummy->next;
+ free(dummy);
+ return result;
+}
+```
+
diff --git a/solution/0000-0099/0002.Add Two Numbers/Solution.c b/solution/0000-0099/0002.Add Two Numbers/Solution.c
new file mode 100644
index 0000000000000..0ca00b4bd6752
--- /dev/null
+++ b/solution/0000-0099/0002.Add Two Numbers/Solution.c
@@ -0,0 +1,41 @@
+
+/**
+ * Definition for singly-linked list.
+ * struct ListNode {
+ * int val;
+ * struct ListNode *next;
+ * };
+ */
+
+struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
+ struct ListNode* dummy = (struct ListNode*) malloc(sizeof(struct ListNode));
+ dummy->val = 0;
+ dummy->next = NULL;
+ struct ListNode* curr = dummy;
+ int carry = 0;
+
+ while (l1 != NULL || l2 != NULL || carry != 0) {
+ int sum = carry;
+ if (l1 != NULL) {
+ sum += l1->val;
+ l1 = l1->next;
+ }
+ if (l2 != NULL) {
+ sum += l2->val;
+ l2 = l2->next;
+ }
+
+ carry = sum / 10;
+ int val = sum % 10;
+
+ struct ListNode* newNode = (struct ListNode*) malloc(sizeof(struct ListNode));
+ newNode->val = val;
+ newNode->next = NULL;
+ curr->next = newNode;
+ curr = curr->next;
+ }
+
+ struct ListNode* result = dummy->next;
+ free(dummy);
+ return result;
+}
diff --git a/solution/0000-0099/0002.Add Two Numbers/Solution.cpp b/solution/0000-0099/0002.Add Two Numbers/Solution.cpp
index b06a8b66b90b4..0d1b36d111994 100644
--- a/solution/0000-0099/0002.Add Two Numbers/Solution.cpp
+++ b/solution/0000-0099/0002.Add Two Numbers/Solution.cpp
@@ -11,9 +11,9 @@
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
- ListNode* dummy = new ListNode();
+ ListNode dummy;
int carry = 0;
- ListNode* cur = dummy;
+ ListNode* cur = &dummy;
while (l1 || l2 || carry) {
int s = (l1 ? l1->val : 0) + (l2 ? l2->val : 0) + carry;
carry = s / 10;
@@ -22,6 +22,6 @@ class Solution {
l1 = l1 ? l1->next : nullptr;
l2 = l2 ? l2->next : nullptr;
}
- return dummy->next;
+ return dummy.next;
}
};
\ No newline at end of file
diff --git a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/README.md b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/README.md
index f502d2ad9b027..d95ea8a5d77a9 100644
--- a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/README.md
+++ b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/README.md
@@ -300,6 +300,33 @@ class Solution {
}
```
+#### C
+
+```c
+int lengthOfLongestSubstring(char* s) {
+ int freq[256] = {0};
+ int l = 0, r = 0;
+ int ans = 0;
+ int len = strlen(s);
+
+ for (r = 0; r < len; r++) {
+ char c = s[r];
+ freq[(unsigned char) c]++;
+
+ while (freq[(unsigned char) c] > 1) {
+ freq[(unsigned char) s[l]]--;
+ l++;
+ }
+
+ if (ans < r - l + 1) {
+ ans = r - l + 1;
+ }
+ }
+
+ return ans;
+}
+```
+
diff --git a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/README_EN.md b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/README_EN.md
index c8302cd9b1aab..16624fcc16b80 100644
--- a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/README_EN.md
+++ b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/README_EN.md
@@ -18,7 +18,7 @@ tags:
-Given a string s
, find the length of the longest substring without repeating characters.
+Given a string s
, find the length of the longest substring without duplicate characters.
Example 1:
@@ -298,6 +298,33 @@ class Solution {
}
```
+#### C
+
+```c
+int lengthOfLongestSubstring(char* s) {
+ int freq[256] = {0};
+ int l = 0, r = 0;
+ int ans = 0;
+ int len = strlen(s);
+
+ for (r = 0; r < len; r++) {
+ char c = s[r];
+ freq[(unsigned char) c]++;
+
+ while (freq[(unsigned char) c] > 1) {
+ freq[(unsigned char) s[l]]--;
+ l++;
+ }
+
+ if (ans < r - l + 1) {
+ ans = r - l + 1;
+ }
+ }
+
+ return ans;
+}
+```
+
diff --git a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.c b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.c
new file mode 100644
index 0000000000000..673e098af92ac
--- /dev/null
+++ b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/Solution.c
@@ -0,0 +1,22 @@
+int lengthOfLongestSubstring(char* s) {
+ int freq[256] = {0};
+ int l = 0, r = 0;
+ int ans = 0;
+ int len = strlen(s);
+
+ for (r = 0; r < len; r++) {
+ char c = s[r];
+ freq[(unsigned char) c]++;
+
+ while (freq[(unsigned char) c] > 1) {
+ freq[(unsigned char) s[l]]--;
+ l++;
+ }
+
+ if (ans < r - l + 1) {
+ ans = r - l + 1;
+ }
+ }
+
+ return ans;
+}
diff --git a/solution/0000-0099/0004.Median of Two Sorted Arrays/README.md b/solution/0000-0099/0004.Median of Two Sorted Arrays/README.md
index a0c5af52f0caa..b6a21c5b7e751 100644
--- a/solution/0000-0099/0004.Median of Two Sorted Arrays/README.md
+++ b/solution/0000-0099/0004.Median of Two Sorted Arrays/README.md
@@ -350,6 +350,36 @@ proc medianOfTwoSortedArrays(nums1: seq[int], nums2: seq[int]): float =
# echo medianOfTwoSortedArrays(arrA, arrB)
```
+#### C
+
+```c
+int findKth(int* nums1, int m, int i, int* nums2, int n, int j, int k) {
+ if (i >= m)
+ return nums2[j + k - 1];
+ if (j >= n)
+ return nums1[i + k - 1];
+ if (k == 1)
+ return nums1[i] < nums2[j] ? nums1[i] : nums2[j];
+
+ int p = k / 2;
+
+ int x = (i + p - 1 < m) ? nums1[i + p - 1] : INT_MAX;
+ int y = (j + p - 1 < n) ? nums2[j + p - 1] : INT_MAX;
+
+ if (x < y)
+ return findKth(nums1, m, i + p, nums2, n, j, k - p);
+ else
+ return findKth(nums1, m, i, nums2, n, j + p, k - p);
+}
+
+double findMedianSortedArrays(int* nums1, int m, int* nums2, int n) {
+ int total = m + n;
+ int a = findKth(nums1, m, 0, nums2, n, 0, (total + 1) / 2);
+ int b = findKth(nums1, m, 0, nums2, n, 0, (total + 2) / 2);
+ return (a + b) / 2.0;
+}
+```
+
diff --git a/solution/0000-0099/0004.Median of Two Sorted Arrays/README_EN.md b/solution/0000-0099/0004.Median of Two Sorted Arrays/README_EN.md
index 15b73ee6ff6f0..2896e96ddc3af 100644
--- a/solution/0000-0099/0004.Median of Two Sorted Arrays/README_EN.md
+++ b/solution/0000-0099/0004.Median of Two Sorted Arrays/README_EN.md
@@ -346,6 +346,36 @@ proc medianOfTwoSortedArrays(nums1: seq[int], nums2: seq[int]): float =
# echo medianOfTwoSortedArrays(arrA, arrB)
```
+#### C
+
+```c
+int findKth(int* nums1, int m, int i, int* nums2, int n, int j, int k) {
+ if (i >= m)
+ return nums2[j + k - 1];
+ if (j >= n)
+ return nums1[i + k - 1];
+ if (k == 1)
+ return nums1[i] < nums2[j] ? nums1[i] : nums2[j];
+
+ int p = k / 2;
+
+ int x = (i + p - 1 < m) ? nums1[i + p - 1] : INT_MAX;
+ int y = (j + p - 1 < n) ? nums2[j + p - 1] : INT_MAX;
+
+ if (x < y)
+ return findKth(nums1, m, i + p, nums2, n, j, k - p);
+ else
+ return findKth(nums1, m, i, nums2, n, j + p, k - p);
+}
+
+double findMedianSortedArrays(int* nums1, int m, int* nums2, int n) {
+ int total = m + n;
+ int a = findKth(nums1, m, 0, nums2, n, 0, (total + 1) / 2);
+ int b = findKth(nums1, m, 0, nums2, n, 0, (total + 2) / 2);
+ return (a + b) / 2.0;
+}
+```
+
diff --git a/solution/0000-0099/0004.Median of Two Sorted Arrays/Solution.c b/solution/0000-0099/0004.Median of Two Sorted Arrays/Solution.c
new file mode 100644
index 0000000000000..2786c7ef9bfd8
--- /dev/null
+++ b/solution/0000-0099/0004.Median of Two Sorted Arrays/Solution.c
@@ -0,0 +1,25 @@
+int findKth(int* nums1, int m, int i, int* nums2, int n, int j, int k) {
+ if (i >= m)
+ return nums2[j + k - 1];
+ if (j >= n)
+ return nums1[i + k - 1];
+ if (k == 1)
+ return nums1[i] < nums2[j] ? nums1[i] : nums2[j];
+
+ int p = k / 2;
+
+ int x = (i + p - 1 < m) ? nums1[i + p - 1] : INT_MAX;
+ int y = (j + p - 1 < n) ? nums2[j + p - 1] : INT_MAX;
+
+ if (x < y)
+ return findKth(nums1, m, i + p, nums2, n, j, k - p);
+ else
+ return findKth(nums1, m, i, nums2, n, j + p, k - p);
+}
+
+double findMedianSortedArrays(int* nums1, int m, int* nums2, int n) {
+ int total = m + n;
+ int a = findKth(nums1, m, 0, nums2, n, 0, (total + 1) / 2);
+ int b = findKth(nums1, m, 0, nums2, n, 0, (total + 2) / 2);
+ return (a + b) / 2.0;
+}
diff --git a/solution/0000-0099/0005.Longest Palindromic Substring/README.md b/solution/0000-0099/0005.Longest Palindromic Substring/README.md
index 11a6b7df01a67..c6c52ab64cd4f 100644
--- a/solution/0000-0099/0005.Longest Palindromic Substring/README.md
+++ b/solution/0000-0099/0005.Longest Palindromic Substring/README.md
@@ -277,6 +277,42 @@ public class Solution {
}
```
+#### C
+
+```c
+char* longestPalindrome(char* s) {
+ int n = strlen(s);
+ bool** f = (bool**) malloc(n * sizeof(bool*));
+ for (int i = 0; i < n; ++i) {
+ f[i] = (bool*) malloc(n * sizeof(bool));
+ for (int j = 0; j < n; ++j) {
+ f[i][j] = true;
+ }
+ }
+ int k = 0, mx = 1;
+ for (int i = n - 2; ~i; --i) {
+ for (int j = i + 1; j < n; ++j) {
+ f[i][j] = false;
+ if (s[i] == s[j]) {
+ f[i][j] = f[i + 1][j - 1];
+ if (f[i][j] && mx < j - i + 1) {
+ mx = j - i + 1;
+ k = i;
+ }
+ }
+ }
+ }
+ char* res = (char*) malloc((mx + 1) * sizeof(char));
+ strncpy(res, s + k, mx);
+ res[mx] = '\0';
+ for (int i = 0; i < n; ++i) {
+ free(f[i]);
+ }
+ free(f);
+ return res;
+}
+```
+
#### Nim
```nim
diff --git a/solution/0000-0099/0005.Longest Palindromic Substring/README_EN.md b/solution/0000-0099/0005.Longest Palindromic Substring/README_EN.md
index 4ac2610fb4e8e..e317ceda58ac4 100644
--- a/solution/0000-0099/0005.Longest Palindromic Substring/README_EN.md
+++ b/solution/0000-0099/0005.Longest Palindromic Substring/README_EN.md
@@ -275,6 +275,42 @@ public class Solution {
}
```
+#### C
+
+```c
+char* longestPalindrome(char* s) {
+ int n = strlen(s);
+ bool** f = (bool**) malloc(n * sizeof(bool*));
+ for (int i = 0; i < n; ++i) {
+ f[i] = (bool*) malloc(n * sizeof(bool));
+ for (int j = 0; j < n; ++j) {
+ f[i][j] = true;
+ }
+ }
+ int k = 0, mx = 1;
+ for (int i = n - 2; ~i; --i) {
+ for (int j = i + 1; j < n; ++j) {
+ f[i][j] = false;
+ if (s[i] == s[j]) {
+ f[i][j] = f[i + 1][j - 1];
+ if (f[i][j] && mx < j - i + 1) {
+ mx = j - i + 1;
+ k = i;
+ }
+ }
+ }
+ }
+ char* res = (char*) malloc((mx + 1) * sizeof(char));
+ strncpy(res, s + k, mx);
+ res[mx] = '\0';
+ for (int i = 0; i < n; ++i) {
+ free(f[i]);
+ }
+ free(f);
+ return res;
+}
+```
+
#### Nim
```nim
diff --git a/solution/0000-0099/0005.Longest Palindromic Substring/Solution.c b/solution/0000-0099/0005.Longest Palindromic Substring/Solution.c
new file mode 100644
index 0000000000000..e5a88d6c8c467
--- /dev/null
+++ b/solution/0000-0099/0005.Longest Palindromic Substring/Solution.c
@@ -0,0 +1,31 @@
+char* longestPalindrome(char* s) {
+ int n = strlen(s);
+ bool** f = (bool**) malloc(n * sizeof(bool*));
+ for (int i = 0; i < n; ++i) {
+ f[i] = (bool*) malloc(n * sizeof(bool));
+ for (int j = 0; j < n; ++j) {
+ f[i][j] = true;
+ }
+ }
+ int k = 0, mx = 1;
+ for (int i = n - 2; ~i; --i) {
+ for (int j = i + 1; j < n; ++j) {
+ f[i][j] = false;
+ if (s[i] == s[j]) {
+ f[i][j] = f[i + 1][j - 1];
+ if (f[i][j] && mx < j - i + 1) {
+ mx = j - i + 1;
+ k = i;
+ }
+ }
+ }
+ }
+ char* res = (char*) malloc((mx + 1) * sizeof(char));
+ strncpy(res, s + k, mx);
+ res[mx] = '\0';
+ for (int i = 0; i < n; ++i) {
+ free(f[i]);
+ }
+ free(f);
+ return res;
+}
diff --git a/solution/0000-0099/0006.Zigzag Conversion/README.md b/solution/0000-0099/0006.Zigzag Conversion/README.md
index c12bad03a22aa..ee8279b690b66 100644
--- a/solution/0000-0099/0006.Zigzag Conversion/README.md
+++ b/solution/0000-0099/0006.Zigzag Conversion/README.md
@@ -78,9 +78,9 @@ P I
### 方法一:模拟
-我们用一个二维数组 $g$ 来模拟 $Z$ 字形排列的过程,其中 $g[i][j]$ 表示第 $i$ 行第 $j$ 列的字符。初始时 $i=0$,另外我们定义一个方向变量 $k$,初始时 $k=-1$,表示向上走。
+我们用一个二维数组 $g$ 来模拟 Z 字形排列的过程,其中 $g[i][j]$ 表示第 $i$ 行第 $j$ 列的字符。初始时 $i = 0$,另外我们定义一个方向变量 $k$,初始时 $k = -1$,表示向上走。
-我们从左到右遍历字符串 $s$,每次遍历到一个字符 $c$,将其追加到 $g[i]$ 中,如果此时 $i=0$ 或者 $i=numRows-1$,说明当前字符位于 $Z$ 字形排列的拐点,我们将 $k$ 的值反转,即 $k=-k$。接下来,我们将 $i$ 的值更新为 $i+k$,即向上或向下移动一行。继续遍历下一个字符,直到遍历完字符串 $s$,我们返回 $g$ 中所有行拼接后的字符串即可。
+我们从左到右遍历字符串 $s$,每次遍历到一个字符 $c$,将其追加到 $g[i]$ 中。如果此时 $i = 0$ 或者 $i = \textit{numRows} - 1$,说明当前字符位于 Z 字形排列的拐点,我们将 $k$ 的值反转,即 $k = -k$。接下来,我们将 $i$ 的值更新为 $i + k$,即向上或向下移动一行。继续遍历下一个字符,直到遍历完字符串 $s$,我们返回 $g$ 中所有行拼接后的字符串即可。
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为字符串 $s$ 的长度。
@@ -199,29 +199,24 @@ function convert(s: string, numRows: number): string {
```rust
impl Solution {
pub fn convert(s: String, num_rows: i32) -> String {
- let num_rows = num_rows as usize;
if num_rows == 1 {
return s;
}
- let mut ss = vec![String::new(); num_rows];
+
+ let num_rows = num_rows as usize;
+ let mut g = vec![String::new(); num_rows];
let mut i = 0;
- let mut to_down = true;
+ let mut k = -1;
+
for c in s.chars() {
- ss[i].push(c);
- if to_down {
- i += 1;
- } else {
- i -= 1;
- }
+ g[i].push(c);
if i == 0 || i == num_rows - 1 {
- to_down = !to_down;
+ k = -k;
}
+ i = (i as isize + k) as usize;
}
- let mut res = String::new();
- for i in 0..num_rows {
- res += &ss[i];
- }
- res
+
+ g.concat()
}
}
```
@@ -282,213 +277,77 @@ public class Solution {
}
```
-
-
-
-
-
-
-### 方法二
-
-
-
-#### Python3
-
-```python
-class Solution:
- def convert(self, s: str, numRows: int) -> str:
- if numRows == 1:
- return s
- group = 2 * numRows - 2
- ans = []
- for i in range(1, numRows + 1):
- interval = group if i == numRows else 2 * numRows - 2 * i
- idx = i - 1
- while idx < len(s):
- ans.append(s[idx])
- idx += interval
- interval = group - interval
- if interval == 0:
- interval = group
- return ''.join(ans)
-```
-
-#### Java
+#### C
-```java
-class Solution {
- public String convert(String s, int numRows) {
- if (numRows == 1) {
- return s;
- }
- StringBuilder ans = new StringBuilder();
- int group = 2 * numRows - 2;
- for (int i = 1; i <= numRows; i++) {
- int interval = i == numRows ? group : 2 * numRows - 2 * i;
- int idx = i - 1;
- while (idx < s.length()) {
- ans.append(s.charAt(idx));
- idx += interval;
- interval = group - interval;
- if (interval == 0) {
- interval = group;
- }
- }
- }
- return ans.toString();
+```c
+char* convert(char* s, int numRows) {
+ if (numRows == 1) {
+ return strdup(s);
}
-}
-```
-#### C++
+ int len = strlen(s);
+ char** g = (char**) malloc(numRows * sizeof(char*));
+ int* idx = (int*) malloc(numRows * sizeof(int));
+ for (int i = 0; i < numRows; ++i) {
+ g[i] = (char*) malloc((len + 1) * sizeof(char));
+ idx[i] = 0;
+ }
-```cpp
-class Solution {
-public:
- string convert(string s, int numRows) {
- if (numRows == 1) return s;
- string ans;
- int group = 2 * numRows - 2;
- for (int i = 1; i <= numRows; ++i) {
- int interval = i == numRows ? group : 2 * numRows - 2 * i;
- int idx = i - 1;
- while (idx < s.length()) {
- ans.push_back(s[idx]);
- idx += interval;
- interval = group - interval;
- if (interval == 0) interval = group;
- }
+ int i = 0, k = -1;
+ for (int p = 0; p < len; ++p) {
+ g[i][idx[i]++] = s[p];
+ if (i == 0 || i == numRows - 1) {
+ k = -k;
}
- return ans;
+ i += k;
}
-};
-```
-#### Go
-
-```go
-func convert(s string, numRows int) string {
- if numRows == 1 {
- return s
- }
- n := len(s)
- ans := make([]byte, n)
- step := 2*numRows - 2
- count := 0
- for i := 0; i < numRows; i++ {
- for j := 0; j+i < n; j += step {
- ans[count] = s[i+j]
- count++
- if i != 0 && i != numRows-1 && j+step-i < n {
- ans[count] = s[j+step-i]
- count++
- }
- }
- }
- return string(ans)
-}
-```
-
-#### TypeScript
-
-```ts
-function convert(s: string, numRows: number): string {
- if (numRows === 1) {
- return s;
- }
- const ss = new Array(numRows).fill('');
- let i = 0;
- let toDown = true;
- for (const c of s) {
- ss[i] += c;
- if (toDown) {
- i++;
- } else {
- i--;
- }
- if (i === 0 || i === numRows - 1) {
- toDown = !toDown;
+ char* ans = (char*) malloc((len + 1) * sizeof(char));
+ int pos = 0;
+ for (int r = 0; r < numRows; ++r) {
+ for (int j = 0; j < idx[r]; ++j) {
+ ans[pos++] = g[r][j];
}
+ free(g[r]);
}
- return ss.reduce((r, s) => r + s);
-}
-```
-
-#### Rust
+ ans[pos] = '\0';
-```rust
-impl Solution {
- pub fn convert(s: String, num_rows: i32) -> String {
- let num_rows = num_rows as usize;
- let mut rows = vec![String::new(); num_rows];
- let iter = (0..num_rows).chain((1..num_rows - 1).rev()).cycle();
- iter.zip(s.chars()).for_each(|(i, c)| rows[i].push(c));
- rows.into_iter().collect()
- }
+ free(g);
+ free(idx);
+ return ans;
}
```
-#### JavaScript
-
-```js
-/**
- * @param {string} s
- * @param {number} numRows
- * @return {string}
- */
-var convert = function (s, numRows) {
- if (numRows == 1) return s;
- const arr = new Array(numRows);
- for (let i = 0; i < numRows; i++) arr[i] = [];
- let mi = 0,
- isDown = true;
- for (const c of s) {
- arr[mi].push(c);
-
- if (mi >= numRows - 1) isDown = false;
- else if (mi <= 0) isDown = true;
-
- if (isDown) mi++;
- else mi--;
- }
- let ans = [];
- for (const item of arr) {
- ans = ans.concat(item);
- }
- return ans.join('');
-};
-```
-
#### PHP
```php
class Solution {
/**
- * @param string $s
- * @param int $numRows
- * @return string
+ * @param String $s
+ * @param Integer $numRows
+ * @return String
*/
-
function convert($s, $numRows) {
- if ($numRows == 1 || strlen($s) <= $numRows) {
+ if ($numRows == 1) {
return $s;
}
- $result = '';
- $cycleLength = 2 * $numRows - 2;
- $n = strlen($s);
+ $g = array_fill(0, $numRows, '');
+ $i = 0;
+ $k = -1;
- for ($i = 0; $i < $numRows; $i++) {
- for ($j = 0; $j + $i < $n; $j += $cycleLength) {
- $result .= $s[$j + $i];
+ $length = strlen($s);
+ for ($j = 0; $j < $length; $j++) {
+ $c = $s[$j];
+ $g[$i] .= $c;
- if ($i != 0 && $i != $numRows - 1 && $j + $cycleLength - $i < $n) {
- $result .= $s[$j + $cycleLength - $i];
- }
+ if ($i == 0 || $i == $numRows - 1) {
+ $k = -$k;
}
- }
- return $result;
+ $i += $k;
+ }
+ return implode('', $g);
}
}
```
diff --git a/solution/0000-0099/0006.Zigzag Conversion/README_EN.md b/solution/0000-0099/0006.Zigzag Conversion/README_EN.md
index 04390da8f24e7..bf557fa6ee583 100644
--- a/solution/0000-0099/0006.Zigzag Conversion/README_EN.md
+++ b/solution/0000-0099/0006.Zigzag Conversion/README_EN.md
@@ -76,11 +76,11 @@ P I
### Solution 1: Simulation
-We use a two-dimensional array $g$ to simulate the process of the $Z$-shape arrangement, where $g[i][j]$ represents the character at the $i$-th row and the $j$-th column. Initially, $i=0$, and we define a direction variable $k$, initially $k=-1$, indicating moving upwards.
+We use a 2D array $g$ to simulate the process of arranging the string in a zigzag pattern, where $g[i][j]$ represents the character at row $i$ and column $j$. Initially, $i = 0$. We also define a direction variable $k$, initially $k = -1$, which means moving upwards.
-We traverse the string $s$ from left to right. Each time we traverse to a character $c$, we append it to $g[i]$. If $i=0$ or $i=numRows-1$ at this time, it means that the current character is at the turning point of the $Z$-shape arrangement, and we reverse the value of $k$, i.e., $k=-k$. Next, we update the value of $i$ to $i+k$, i.e., move up or down one row. Continue to traverse the next character until we have traversed the string $s$, and we return the string concatenated by all rows in $g$.
+We traverse the string $s$ from left to right. For each character $c$, we append it to $g[i]$. If $i = 0$ or $i = \textit{numRows} - 1$, it means the current character is at a turning point in the zigzag pattern, so we reverse the value of $k$, i.e., $k = -k$. Then, we update $i$ to $i + k$, which means moving up or down one row. Continue traversing the next character until the end of the string $s$. Finally, we return the concatenation of all rows in $g$ as the result.
-The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the string $s$.
+The time complexity is $O(n)$ and the space complexity is $O(n)$, where $n$ is the length of the string $s$.
@@ -197,29 +197,24 @@ function convert(s: string, numRows: number): string {
```rust
impl Solution {
pub fn convert(s: String, num_rows: i32) -> String {
- let num_rows = num_rows as usize;
if num_rows == 1 {
return s;
}
- let mut ss = vec![String::new(); num_rows];
+
+ let num_rows = num_rows as usize;
+ let mut g = vec![String::new(); num_rows];
let mut i = 0;
- let mut to_down = true;
+ let mut k = -1;
+
for c in s.chars() {
- ss[i].push(c);
- if to_down {
- i += 1;
- } else {
- i -= 1;
- }
+ g[i].push(c);
if i == 0 || i == num_rows - 1 {
- to_down = !to_down;
+ k = -k;
}
+ i = (i as isize + k) as usize;
}
- let mut res = String::new();
- for i in 0..num_rows {
- res += &ss[i];
- }
- res
+
+ g.concat()
}
}
```
@@ -280,213 +275,77 @@ public class Solution {
}
```
-
-
-
-
-
-
-### Solution 2
-
-
-
-#### Python3
-
-```python
-class Solution:
- def convert(self, s: str, numRows: int) -> str:
- if numRows == 1:
- return s
- group = 2 * numRows - 2
- ans = []
- for i in range(1, numRows + 1):
- interval = group if i == numRows else 2 * numRows - 2 * i
- idx = i - 1
- while idx < len(s):
- ans.append(s[idx])
- idx += interval
- interval = group - interval
- if interval == 0:
- interval = group
- return ''.join(ans)
-```
-
-#### Java
+#### C
-```java
-class Solution {
- public String convert(String s, int numRows) {
- if (numRows == 1) {
- return s;
- }
- StringBuilder ans = new StringBuilder();
- int group = 2 * numRows - 2;
- for (int i = 1; i <= numRows; i++) {
- int interval = i == numRows ? group : 2 * numRows - 2 * i;
- int idx = i - 1;
- while (idx < s.length()) {
- ans.append(s.charAt(idx));
- idx += interval;
- interval = group - interval;
- if (interval == 0) {
- interval = group;
- }
- }
- }
- return ans.toString();
+```c
+char* convert(char* s, int numRows) {
+ if (numRows == 1) {
+ return strdup(s);
}
-}
-```
-#### C++
+ int len = strlen(s);
+ char** g = (char**) malloc(numRows * sizeof(char*));
+ int* idx = (int*) malloc(numRows * sizeof(int));
+ for (int i = 0; i < numRows; ++i) {
+ g[i] = (char*) malloc((len + 1) * sizeof(char));
+ idx[i] = 0;
+ }
-```cpp
-class Solution {
-public:
- string convert(string s, int numRows) {
- if (numRows == 1) return s;
- string ans;
- int group = 2 * numRows - 2;
- for (int i = 1; i <= numRows; ++i) {
- int interval = i == numRows ? group : 2 * numRows - 2 * i;
- int idx = i - 1;
- while (idx < s.length()) {
- ans.push_back(s[idx]);
- idx += interval;
- interval = group - interval;
- if (interval == 0) interval = group;
- }
+ int i = 0, k = -1;
+ for (int p = 0; p < len; ++p) {
+ g[i][idx[i]++] = s[p];
+ if (i == 0 || i == numRows - 1) {
+ k = -k;
}
- return ans;
+ i += k;
}
-};
-```
-#### Go
-
-```go
-func convert(s string, numRows int) string {
- if numRows == 1 {
- return s
- }
- n := len(s)
- ans := make([]byte, n)
- step := 2*numRows - 2
- count := 0
- for i := 0; i < numRows; i++ {
- for j := 0; j+i < n; j += step {
- ans[count] = s[i+j]
- count++
- if i != 0 && i != numRows-1 && j+step-i < n {
- ans[count] = s[j+step-i]
- count++
- }
- }
- }
- return string(ans)
-}
-```
-
-#### TypeScript
-
-```ts
-function convert(s: string, numRows: number): string {
- if (numRows === 1) {
- return s;
- }
- const ss = new Array(numRows).fill('');
- let i = 0;
- let toDown = true;
- for (const c of s) {
- ss[i] += c;
- if (toDown) {
- i++;
- } else {
- i--;
- }
- if (i === 0 || i === numRows - 1) {
- toDown = !toDown;
+ char* ans = (char*) malloc((len + 1) * sizeof(char));
+ int pos = 0;
+ for (int r = 0; r < numRows; ++r) {
+ for (int j = 0; j < idx[r]; ++j) {
+ ans[pos++] = g[r][j];
}
+ free(g[r]);
}
- return ss.reduce((r, s) => r + s);
-}
-```
-
-#### Rust
+ ans[pos] = '\0';
-```rust
-impl Solution {
- pub fn convert(s: String, num_rows: i32) -> String {
- let num_rows = num_rows as usize;
- let mut rows = vec![String::new(); num_rows];
- let iter = (0..num_rows).chain((1..num_rows - 1).rev()).cycle();
- iter.zip(s.chars()).for_each(|(i, c)| rows[i].push(c));
- rows.into_iter().collect()
- }
+ free(g);
+ free(idx);
+ return ans;
}
```
-#### JavaScript
-
-```js
-/**
- * @param {string} s
- * @param {number} numRows
- * @return {string}
- */
-var convert = function (s, numRows) {
- if (numRows == 1) return s;
- const arr = new Array(numRows);
- for (let i = 0; i < numRows; i++) arr[i] = [];
- let mi = 0,
- isDown = true;
- for (const c of s) {
- arr[mi].push(c);
-
- if (mi >= numRows - 1) isDown = false;
- else if (mi <= 0) isDown = true;
-
- if (isDown) mi++;
- else mi--;
- }
- let ans = [];
- for (const item of arr) {
- ans = ans.concat(item);
- }
- return ans.join('');
-};
-```
-
#### PHP
```php
class Solution {
/**
- * @param string $s
- * @param int $numRows
- * @return string
+ * @param String $s
+ * @param Integer $numRows
+ * @return String
*/
-
function convert($s, $numRows) {
- if ($numRows == 1 || strlen($s) <= $numRows) {
+ if ($numRows == 1) {
return $s;
}
- $result = '';
- $cycleLength = 2 * $numRows - 2;
- $n = strlen($s);
+ $g = array_fill(0, $numRows, '');
+ $i = 0;
+ $k = -1;
- for ($i = 0; $i < $numRows; $i++) {
- for ($j = 0; $j + $i < $n; $j += $cycleLength) {
- $result .= $s[$j + $i];
+ $length = strlen($s);
+ for ($j = 0; $j < $length; $j++) {
+ $c = $s[$j];
+ $g[$i] .= $c;
- if ($i != 0 && $i != $numRows - 1 && $j + $cycleLength - $i < $n) {
- $result .= $s[$j + $cycleLength - $i];
- }
+ if ($i == 0 || $i == $numRows - 1) {
+ $k = -$k;
}
- }
- return $result;
+ $i += $k;
+ }
+ return implode('', $g);
}
}
```
diff --git a/solution/0000-0099/0006.Zigzag Conversion/Solution.c b/solution/0000-0099/0006.Zigzag Conversion/Solution.c
new file mode 100644
index 0000000000000..3111a73e7035c
--- /dev/null
+++ b/solution/0000-0099/0006.Zigzag Conversion/Solution.c
@@ -0,0 +1,36 @@
+char* convert(char* s, int numRows) {
+ if (numRows == 1) {
+ return strdup(s);
+ }
+
+ int len = strlen(s);
+ char** g = (char**) malloc(numRows * sizeof(char*));
+ int* idx = (int*) malloc(numRows * sizeof(int));
+ for (int i = 0; i < numRows; ++i) {
+ g[i] = (char*) malloc((len + 1) * sizeof(char));
+ idx[i] = 0;
+ }
+
+ int i = 0, k = -1;
+ for (int p = 0; p < len; ++p) {
+ g[i][idx[i]++] = s[p];
+ if (i == 0 || i == numRows - 1) {
+ k = -k;
+ }
+ i += k;
+ }
+
+ char* ans = (char*) malloc((len + 1) * sizeof(char));
+ int pos = 0;
+ for (int r = 0; r < numRows; ++r) {
+ for (int j = 0; j < idx[r]; ++j) {
+ ans[pos++] = g[r][j];
+ }
+ free(g[r]);
+ }
+ ans[pos] = '\0';
+
+ free(g);
+ free(idx);
+ return ans;
+}
diff --git a/solution/0000-0099/0006.Zigzag Conversion/Solution.php b/solution/0000-0099/0006.Zigzag Conversion/Solution.php
index 4eb4ee9795308..2d151b664b8f6 100644
--- a/solution/0000-0099/0006.Zigzag Conversion/Solution.php
+++ b/solution/0000-0099/0006.Zigzag Conversion/Solution.php
@@ -1,29 +1,29 @@
class Solution {
/**
- * @param string $s
- * @param int $numRows
- * @return string
+ * @param String $s
+ * @param Integer $numRows
+ * @return String
*/
-
function convert($s, $numRows) {
- if ($numRows == 1 || strlen($s) <= $numRows) {
+ if ($numRows == 1) {
return $s;
}
- $result = '';
- $cycleLength = 2 * $numRows - 2;
- $n = strlen($s);
+ $g = array_fill(0, $numRows, "");
+ $i = 0;
+ $k = -1;
- for ($i = 0; $i < $numRows; $i++) {
- for ($j = 0; $j + $i < $n; $j += $cycleLength) {
- $result .= $s[$j + $i];
+ $length = strlen($s);
+ for ($j = 0; $j < $length; $j++) {
+ $c = $s[$j];
+ $g[$i] .= $c;
- if ($i != 0 && $i != $numRows - 1 && $j + $cycleLength - $i < $n) {
- $result .= $s[$j + $cycleLength - $i];
- }
+ if ($i == 0 || $i == $numRows - 1) {
+ $k = -$k;
}
- }
- return $result;
+ $i += $k;
+ }
+ return implode("", $g);
}
}
diff --git a/solution/0000-0099/0006.Zigzag Conversion/Solution.rs b/solution/0000-0099/0006.Zigzag Conversion/Solution.rs
index bfbf876018144..2a4e99f2b0433 100644
--- a/solution/0000-0099/0006.Zigzag Conversion/Solution.rs
+++ b/solution/0000-0099/0006.Zigzag Conversion/Solution.rs
@@ -1,27 +1,22 @@
impl Solution {
pub fn convert(s: String, num_rows: i32) -> String {
- let num_rows = num_rows as usize;
if num_rows == 1 {
return s;
}
- let mut ss = vec![String::new(); num_rows];
+
+ let num_rows = num_rows as usize;
+ let mut g = vec![String::new(); num_rows];
let mut i = 0;
- let mut to_down = true;
+ let mut k = -1;
+
for c in s.chars() {
- ss[i].push(c);
- if to_down {
- i += 1;
- } else {
- i -= 1;
- }
+ g[i].push(c);
if i == 0 || i == num_rows - 1 {
- to_down = !to_down;
+ k = -k;
}
+ i = (i as isize + k) as usize;
}
- let mut res = String::new();
- for i in 0..num_rows {
- res += &ss[i];
- }
- res
+
+ g.concat()
}
}
diff --git a/solution/0000-0099/0006.Zigzag Conversion/Solution2.cpp b/solution/0000-0099/0006.Zigzag Conversion/Solution2.cpp
deleted file mode 100644
index f66b5d959b459..0000000000000
--- a/solution/0000-0099/0006.Zigzag Conversion/Solution2.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-class Solution {
-public:
- string convert(string s, int numRows) {
- if (numRows == 1) return s;
- string ans;
- int group = 2 * numRows - 2;
- for (int i = 1; i <= numRows; ++i) {
- int interval = i == numRows ? group : 2 * numRows - 2 * i;
- int idx = i - 1;
- while (idx < s.length()) {
- ans.push_back(s[idx]);
- idx += interval;
- interval = group - interval;
- if (interval == 0) interval = group;
- }
- }
- return ans;
- }
-};
\ No newline at end of file
diff --git a/solution/0000-0099/0006.Zigzag Conversion/Solution2.go b/solution/0000-0099/0006.Zigzag Conversion/Solution2.go
deleted file mode 100644
index acc9934f620c5..0000000000000
--- a/solution/0000-0099/0006.Zigzag Conversion/Solution2.go
+++ /dev/null
@@ -1,20 +0,0 @@
-func convert(s string, numRows int) string {
- if numRows == 1 {
- return s
- }
- n := len(s)
- ans := make([]byte, n)
- step := 2*numRows - 2
- count := 0
- for i := 0; i < numRows; i++ {
- for j := 0; j+i < n; j += step {
- ans[count] = s[i+j]
- count++
- if i != 0 && i != numRows-1 && j+step-i < n {
- ans[count] = s[j+step-i]
- count++
- }
- }
- }
- return string(ans)
-}
\ No newline at end of file
diff --git a/solution/0000-0099/0006.Zigzag Conversion/Solution2.java b/solution/0000-0099/0006.Zigzag Conversion/Solution2.java
deleted file mode 100644
index b2a9294d752f3..0000000000000
--- a/solution/0000-0099/0006.Zigzag Conversion/Solution2.java
+++ /dev/null
@@ -1,22 +0,0 @@
-class Solution {
- public String convert(String s, int numRows) {
- if (numRows == 1) {
- return s;
- }
- StringBuilder ans = new StringBuilder();
- int group = 2 * numRows - 2;
- for (int i = 1; i <= numRows; i++) {
- int interval = i == numRows ? group : 2 * numRows - 2 * i;
- int idx = i - 1;
- while (idx < s.length()) {
- ans.append(s.charAt(idx));
- idx += interval;
- interval = group - interval;
- if (interval == 0) {
- interval = group;
- }
- }
- }
- return ans.toString();
- }
-}
\ No newline at end of file
diff --git a/solution/0000-0099/0006.Zigzag Conversion/Solution2.js b/solution/0000-0099/0006.Zigzag Conversion/Solution2.js
deleted file mode 100644
index e291e38cb6b18..0000000000000
--- a/solution/0000-0099/0006.Zigzag Conversion/Solution2.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * @param {string} s
- * @param {number} numRows
- * @return {string}
- */
-var convert = function (s, numRows) {
- if (numRows == 1) return s;
- const arr = new Array(numRows);
- for (let i = 0; i < numRows; i++) arr[i] = [];
- let mi = 0,
- isDown = true;
- for (const c of s) {
- arr[mi].push(c);
-
- if (mi >= numRows - 1) isDown = false;
- else if (mi <= 0) isDown = true;
-
- if (isDown) mi++;
- else mi--;
- }
- let ans = [];
- for (const item of arr) {
- ans = ans.concat(item);
- }
- return ans.join('');
-};
diff --git a/solution/0000-0099/0006.Zigzag Conversion/Solution2.py b/solution/0000-0099/0006.Zigzag Conversion/Solution2.py
deleted file mode 100644
index 5fc2f82ff1e5a..0000000000000
--- a/solution/0000-0099/0006.Zigzag Conversion/Solution2.py
+++ /dev/null
@@ -1,16 +0,0 @@
-class Solution:
- def convert(self, s: str, numRows: int) -> str:
- if numRows == 1:
- return s
- group = 2 * numRows - 2
- ans = []
- for i in range(1, numRows + 1):
- interval = group if i == numRows else 2 * numRows - 2 * i
- idx = i - 1
- while idx < len(s):
- ans.append(s[idx])
- idx += interval
- interval = group - interval
- if interval == 0:
- interval = group
- return ''.join(ans)
diff --git a/solution/0000-0099/0006.Zigzag Conversion/Solution2.rs b/solution/0000-0099/0006.Zigzag Conversion/Solution2.rs
deleted file mode 100644
index f824b365dedec..0000000000000
--- a/solution/0000-0099/0006.Zigzag Conversion/Solution2.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-impl Solution {
- pub fn convert(s: String, num_rows: i32) -> String {
- let num_rows = num_rows as usize;
- let mut rows = vec![String::new(); num_rows];
- let iter = (0..num_rows).chain((1..num_rows - 1).rev()).cycle();
- iter.zip(s.chars()).for_each(|(i, c)| rows[i].push(c));
- rows.into_iter().collect()
- }
-}
diff --git a/solution/0000-0099/0006.Zigzag Conversion/Solution2.ts b/solution/0000-0099/0006.Zigzag Conversion/Solution2.ts
deleted file mode 100644
index 3085c8797be67..0000000000000
--- a/solution/0000-0099/0006.Zigzag Conversion/Solution2.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-function convert(s: string, numRows: number): string {
- if (numRows === 1) {
- return s;
- }
- const ss = new Array(numRows).fill('');
- let i = 0;
- let toDown = true;
- for (const c of s) {
- ss[i] += c;
- if (toDown) {
- i++;
- } else {
- i--;
- }
- if (i === 0 || i === numRows - 1) {
- toDown = !toDown;
- }
- }
- return ss.reduce((r, s) => r + s);
-}
diff --git a/solution/0000-0099/0008.String to Integer (atoi)/README.md b/solution/0000-0099/0008.String to Integer (atoi)/README.md
index a1c189c4a6ce7..324738cca1c5e 100644
--- a/solution/0000-0099/0008.String to Integer (atoi)/README.md
+++ b/solution/0000-0099/0008.String to Integer (atoi)/README.md
@@ -214,6 +214,36 @@ class Solution {
}
```
+#### C++
+
+```cpp
+class Solution {
+public:
+ int myAtoi(string s) {
+ int i = 0, n = s.size();
+ while (i < n && s[i] == ' ')
+ ++i;
+
+ int sign = 1;
+ if (i < n && (s[i] == '-' || s[i] == '+')) {
+ sign = s[i] == '-' ? -1 : 1;
+ ++i;
+ }
+
+ int res = 0;
+ while (i < n && isdigit(s[i])) {
+ int digit = s[i] - '0';
+ if (res > INT_MAX / 10 || (res == INT_MAX / 10 && digit > INT_MAX % 10)) {
+ return sign == 1 ? INT_MAX : INT_MIN;
+ }
+ res = res * 10 + digit;
+ ++i;
+ }
+ return res * sign;
+ }
+};
+```
+
#### Go
```go
@@ -356,6 +386,36 @@ class Solution {
}
```
+#### C
+
+```c
+int myAtoi(char* s) {
+ int i = 0;
+
+ while (s[i] == ' ') {
+ i++;
+ }
+
+ int sign = 1;
+ if (s[i] == '-' || s[i] == '+') {
+ sign = (s[i] == '-') ? -1 : 1;
+ i++;
+ }
+
+ int res = 0;
+ while (isdigit(s[i])) {
+ int digit = s[i] - '0';
+ if (res > INT_MAX / 10 || (res == INT_MAX / 10 && digit > INT_MAX % 10)) {
+ return sign == 1 ? INT_MAX : INT_MIN;
+ }
+ res = res * 10 + digit;
+ i++;
+ }
+
+ return res * sign;
+}
+```
+
diff --git a/solution/0000-0099/0008.String to Integer (atoi)/README_EN.md b/solution/0000-0099/0008.String to Integer (atoi)/README_EN.md
index 7603001843b45..bc0c422b89134 100644
--- a/solution/0000-0099/0008.String to Integer (atoi)/README_EN.md
+++ b/solution/0000-0099/0008.String to Integer (atoi)/README_EN.md
@@ -160,7 +160,6 @@ class Solution:
i = 0
while s[i] == ' ':
i += 1
- # 仅包含空格
if i == n:
return 0
sign = -1 if s[i] == '-' else 1
@@ -168,11 +167,9 @@ class Solution:
i += 1
res, flag = 0, (2**31 - 1) // 10
while i < n:
- # 非数字,跳出循环体
if not s[i].isdigit():
break
c = int(s[i])
- # 溢出判断
if res > flag or (res == flag and c > 7):
return 2**31 - 1 if sign > 0 else -(2**31)
res = res * 10 + c
@@ -190,7 +187,6 @@ class Solution {
if (n == 0) return 0;
int i = 0;
while (s.charAt(i) == ' ') {
- // 仅包含空格
if (++i == n) return 0;
}
int sign = 1;
@@ -198,9 +194,7 @@ class Solution {
if (s.charAt(i) == '-' || s.charAt(i) == '+') ++i;
int res = 0, flag = Integer.MAX_VALUE / 10;
for (; i < n; ++i) {
- // 非数字,跳出循环体
if (s.charAt(i) < '0' || s.charAt(i) > '9') break;
- // 溢出判断
if (res > flag || (res == flag && s.charAt(i) > '7'))
return sign > 0 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
res = res * 10 + (s.charAt(i) - '0');
@@ -210,6 +204,36 @@ class Solution {
}
```
+#### C++
+
+```cpp
+class Solution {
+public:
+ int myAtoi(string s) {
+ int i = 0, n = s.size();
+ while (i < n && s[i] == ' ')
+ ++i;
+
+ int sign = 1;
+ if (i < n && (s[i] == '-' || s[i] == '+')) {
+ sign = s[i] == '-' ? -1 : 1;
+ ++i;
+ }
+
+ int res = 0;
+ while (i < n && isdigit(s[i])) {
+ int digit = s[i] - '0';
+ if (res > INT_MAX / 10 || (res == INT_MAX / 10 && digit > INT_MAX % 10)) {
+ return sign == 1 ? INT_MAX : INT_MIN;
+ }
+ res = res * 10 + digit;
+ ++i;
+ }
+ return res * sign;
+ }
+};
+```
+
#### Go
```go
@@ -282,8 +306,6 @@ const myAtoi = function (str) {
#### C#
```cs
-// https://leetcode.com/problems/string-to-integer-atoi/
-
public partial class Solution
{
public int MyAtoi(string str)
@@ -352,6 +374,36 @@ class Solution {
}
```
+#### C
+
+```c
+int myAtoi(char* s) {
+ int i = 0;
+
+ while (s[i] == ' ') {
+ i++;
+ }
+
+ int sign = 1;
+ if (s[i] == '-' || s[i] == '+') {
+ sign = (s[i] == '-') ? -1 : 1;
+ i++;
+ }
+
+ int res = 0;
+ while (isdigit(s[i])) {
+ int digit = s[i] - '0';
+ if (res > INT_MAX / 10 || (res == INT_MAX / 10 && digit > INT_MAX % 10)) {
+ return sign == 1 ? INT_MAX : INT_MIN;
+ }
+ res = res * 10 + digit;
+ i++;
+ }
+
+ return res * sign;
+}
+```
+
diff --git a/solution/0000-0099/0008.String to Integer (atoi)/Solution.c b/solution/0000-0099/0008.String to Integer (atoi)/Solution.c
new file mode 100644
index 0000000000000..26f63ab4316e3
--- /dev/null
+++ b/solution/0000-0099/0008.String to Integer (atoi)/Solution.c
@@ -0,0 +1,25 @@
+int myAtoi(char* s) {
+ int i = 0;
+
+ while (s[i] == ' ') {
+ i++;
+ }
+
+ int sign = 1;
+ if (s[i] == '-' || s[i] == '+') {
+ sign = (s[i] == '-') ? -1 : 1;
+ i++;
+ }
+
+ int res = 0;
+ while (isdigit(s[i])) {
+ int digit = s[i] - '0';
+ if (res > INT_MAX / 10 || (res == INT_MAX / 10 && digit > INT_MAX % 10)) {
+ return sign == 1 ? INT_MAX : INT_MIN;
+ }
+ res = res * 10 + digit;
+ i++;
+ }
+
+ return res * sign;
+}
diff --git a/solution/0000-0099/0008.String to Integer (atoi)/Solution.cpp b/solution/0000-0099/0008.String to Integer (atoi)/Solution.cpp
new file mode 100644
index 0000000000000..72fc381920bf2
--- /dev/null
+++ b/solution/0000-0099/0008.String to Integer (atoi)/Solution.cpp
@@ -0,0 +1,25 @@
+class Solution {
+public:
+ int myAtoi(string s) {
+ int i = 0, n = s.size();
+ while (i < n && s[i] == ' ')
+ ++i;
+
+ int sign = 1;
+ if (i < n && (s[i] == '-' || s[i] == '+')) {
+ sign = s[i] == '-' ? -1 : 1;
+ ++i;
+ }
+
+ int res = 0;
+ while (i < n && isdigit(s[i])) {
+ int digit = s[i] - '0';
+ if (res > INT_MAX / 10 || (res == INT_MAX / 10 && digit > INT_MAX % 10)) {
+ return sign == 1 ? INT_MAX : INT_MIN;
+ }
+ res = res * 10 + digit;
+ ++i;
+ }
+ return res * sign;
+ }
+};
diff --git a/solution/0000-0099/0009.Palindrome Number/README.md b/solution/0000-0099/0009.Palindrome Number/README.md
index 5293dccce090b..46fbfac16ef77 100644
--- a/solution/0000-0099/0009.Palindrome Number/README.md
+++ b/solution/0000-0099/0009.Palindrome Number/README.md
@@ -248,6 +248,24 @@ class Solution {
}
```
+#### C
+
+```c
+bool isPalindrome(int x) {
+ if (x < 0 || (x != 0 && x % 10 == 0)) {
+ return false;
+ }
+
+ int y = 0;
+ while (y < x) {
+ y = y * 10 + x % 10;
+ x /= 10;
+ }
+
+ return (x == y || x == y / 10);
+}
+```
+
diff --git a/solution/0000-0099/0009.Palindrome Number/README_EN.md b/solution/0000-0099/0009.Palindrome Number/README_EN.md
index 8b0ac2e383ca0..712ba430b9d5a 100644
--- a/solution/0000-0099/0009.Palindrome Number/README_EN.md
+++ b/solution/0000-0099/0009.Palindrome Number/README_EN.md
@@ -240,6 +240,24 @@ class Solution {
}
```
+#### C
+
+```c
+bool isPalindrome(int x) {
+ if (x < 0 || (x != 0 && x % 10 == 0)) {
+ return false;
+ }
+
+ int y = 0;
+ while (y < x) {
+ y = y * 10 + x % 10;
+ x /= 10;
+ }
+
+ return (x == y || x == y / 10);
+}
+```
+
diff --git a/solution/0000-0099/0009.Palindrome Number/Solution.c b/solution/0000-0099/0009.Palindrome Number/Solution.c
new file mode 100644
index 0000000000000..c13f8cc7947ca
--- /dev/null
+++ b/solution/0000-0099/0009.Palindrome Number/Solution.c
@@ -0,0 +1,13 @@
+bool isPalindrome(int x) {
+ if (x < 0 || (x != 0 && x % 10 == 0)) {
+ return false;
+ }
+
+ int y = 0;
+ while (y < x) {
+ y = y * 10 + x % 10;
+ x /= 10;
+ }
+
+ return (x == y || x == y / 10);
+}
diff --git a/solution/0000-0099/0010.Regular Expression Matching/README.md b/solution/0000-0099/0010.Regular Expression Matching/README.md
index 5eb9ff8be6f3d..e9acc4602cc81 100644
--- a/solution/0000-0099/0010.Regular Expression Matching/README.md
+++ b/solution/0000-0099/0010.Regular Expression Matching/README.md
@@ -331,6 +331,85 @@ public class Solution {
}
```
+#### C
+
+```c
+#define MAX_LEN 1000
+
+char *ss, *pp;
+int m, n;
+int f[MAX_LEN + 1][MAX_LEN + 1];
+
+bool dfs(int i, int j) {
+ if (j >= n) {
+ return i == m;
+ }
+ if (f[i][j] != 0) {
+ return f[i][j] == 1;
+ }
+ int res = -1;
+ if (j + 1 < n && pp[j + 1] == '*') {
+ if (dfs(i, j + 2) || (i < m && (ss[i] == pp[j] || pp[j] == '.') && dfs(i + 1, j))) {
+ res = 1;
+ }
+ } else if (i < m && (ss[i] == pp[j] || pp[j] == '.') && dfs(i + 1, j + 1)) {
+ res = 1;
+ }
+ f[i][j] = res;
+ return res == 1;
+}
+
+bool isMatch(char* s, char* p) {
+ ss = s;
+ pp = p;
+ m = strlen(s);
+ n = strlen(p);
+ memset(f, 0, sizeof(f));
+ return dfs(0, 0);
+}
+```
+
+#### PHP
+
+```php
+class Solution {
+ /**
+ * @param String $s
+ * @param String $p
+ * @return Boolean
+ */
+ function isMatch($s, $p) {
+ $m = strlen($s);
+ $n = strlen($p);
+ $f = array_fill(0, $m + 1, array_fill(0, $n + 1, 0));
+
+ $dfs = function ($i, $j) use (&$s, &$p, $m, $n, &$f, &$dfs) {
+ if ($j >= $n) {
+ return $i == $m;
+ }
+ if ($f[$i][$j] != 0) {
+ return $f[$i][$j] == 1;
+ }
+ $res = -1;
+ if ($j + 1 < $n && $p[$j + 1] == '*') {
+ if (
+ $dfs($i, $j + 2) ||
+ ($i < $m && ($s[$i] == $p[$j] || $p[$j] == '.') && $dfs($i + 1, $j))
+ ) {
+ $res = 1;
+ }
+ } elseif ($i < $m && ($s[$i] == $p[$j] || $p[$j] == '.') && $dfs($i + 1, $j + 1)) {
+ $res = 1;
+ }
+ $f[$i][$j] = $res;
+ return $res == 1;
+ };
+
+ return $dfs(0, 0);
+ }
+}
+```
+
@@ -541,44 +620,60 @@ public class Solution {
```php
class Solution {
/**
- * @param string $s
- * @param string $p
- * @return boolean
+ * @param String $s
+ * @param String $p
+ * @return Boolean
*/
-
function isMatch($s, $p) {
$m = strlen($s);
$n = strlen($p);
- $dp = array_fill(0, $m + 1, array_fill(0, $n + 1, false));
- $dp[0][0] = true;
-
- for ($j = 1; $j <= $n; $j++) {
- if ($p[$j - 1] == '*') {
- $dp[0][$j] = $dp[0][$j - 2];
- }
- }
+ $f = array_fill(0, $m + 1, array_fill(0, $n + 1, false));
+ $f[0][0] = true;
- for ($i = 1; $i <= $m; $i++) {
+ for ($i = 0; $i <= $m; $i++) {
for ($j = 1; $j <= $n; $j++) {
- if ($p[$j - 1] == '.' || $p[$j - 1] == $s[$i - 1]) {
- $dp[$i][$j] = $dp[$i - 1][$j - 1];
- } elseif ($p[$j - 1] == '*') {
- $dp[$i][$j] = $dp[$i][$j - 2];
- if ($p[$j - 2] == '.' || $p[$j - 2] == $s[$i - 1]) {
- $dp[$i][$j] = $dp[$i][$j] || $dp[$i - 1][$j];
+ if ($p[$j - 1] == '*') {
+ $f[$i][$j] = $f[$i][$j - 2];
+ if ($i > 0 && ($p[$j - 2] == '.' || $p[$j - 2] == $s[$i - 1])) {
+ $f[$i][$j] = $f[$i][$j] || $f[$i - 1][$j];
}
- } else {
- $dp[$i][$j] = false;
+ } elseif ($i > 0 && ($p[$j - 1] == '.' || $p[$j - 1] == $s[$i - 1])) {
+ $f[$i][$j] = $f[$i - 1][$j - 1];
}
}
}
- return $dp[$m][$n];
+ return $f[$m][$n];
}
}
```
+#### C
+
+```c
+bool isMatch(char* s, char* p) {
+ int m = strlen(s), n = strlen(p);
+ bool f[m + 1][n + 1];
+ memset(f, 0, sizeof(f));
+ f[0][0] = true;
+
+ for (int i = 0; i <= m; ++i) {
+ for (int j = 1; j <= n; ++j) {
+ if (p[j - 1] == '*') {
+ f[i][j] = f[i][j - 2];
+ if (i > 0 && (p[j - 2] == '.' || p[j - 2] == s[i - 1])) {
+ f[i][j] = f[i][j] || f[i - 1][j];
+ }
+ } else if (i > 0 && (p[j - 1] == '.' || p[j - 1] == s[i - 1])) {
+ f[i][j] = f[i - 1][j - 1];
+ }
+ }
+ }
+ return f[m][n];
+}
+```
+
diff --git a/solution/0000-0099/0010.Regular Expression Matching/README_EN.md b/solution/0000-0099/0010.Regular Expression Matching/README_EN.md
index d7302fddd9809..3164f471dd8c2 100644
--- a/solution/0000-0099/0010.Regular Expression Matching/README_EN.md
+++ b/solution/0000-0099/0010.Regular Expression Matching/README_EN.md
@@ -330,6 +330,85 @@ public class Solution {
}
```
+#### C
+
+```c
+#define MAX_LEN 1000
+
+char *ss, *pp;
+int m, n;
+int f[MAX_LEN + 1][MAX_LEN + 1];
+
+bool dfs(int i, int j) {
+ if (j >= n) {
+ return i == m;
+ }
+ if (f[i][j] != 0) {
+ return f[i][j] == 1;
+ }
+ int res = -1;
+ if (j + 1 < n && pp[j + 1] == '*') {
+ if (dfs(i, j + 2) || (i < m && (ss[i] == pp[j] || pp[j] == '.') && dfs(i + 1, j))) {
+ res = 1;
+ }
+ } else if (i < m && (ss[i] == pp[j] || pp[j] == '.') && dfs(i + 1, j + 1)) {
+ res = 1;
+ }
+ f[i][j] = res;
+ return res == 1;
+}
+
+bool isMatch(char* s, char* p) {
+ ss = s;
+ pp = p;
+ m = strlen(s);
+ n = strlen(p);
+ memset(f, 0, sizeof(f));
+ return dfs(0, 0);
+}
+```
+
+#### PHP
+
+```php
+class Solution {
+ /**
+ * @param String $s
+ * @param String $p
+ * @return Boolean
+ */
+ function isMatch($s, $p) {
+ $m = strlen($s);
+ $n = strlen($p);
+ $f = array_fill(0, $m + 1, array_fill(0, $n + 1, 0));
+
+ $dfs = function ($i, $j) use (&$s, &$p, $m, $n, &$f, &$dfs) {
+ if ($j >= $n) {
+ return $i == $m;
+ }
+ if ($f[$i][$j] != 0) {
+ return $f[$i][$j] == 1;
+ }
+ $res = -1;
+ if ($j + 1 < $n && $p[$j + 1] == '*') {
+ if (
+ $dfs($i, $j + 2) ||
+ ($i < $m && ($s[$i] == $p[$j] || $p[$j] == '.') && $dfs($i + 1, $j))
+ ) {
+ $res = 1;
+ }
+ } elseif ($i < $m && ($s[$i] == $p[$j] || $p[$j] == '.') && $dfs($i + 1, $j + 1)) {
+ $res = 1;
+ }
+ $f[$i][$j] = $res;
+ return $res == 1;
+ };
+
+ return $dfs(0, 0);
+ }
+}
+```
+
@@ -540,44 +619,60 @@ public class Solution {
```php
class Solution {
/**
- * @param string $s
- * @param string $p
- * @return boolean
+ * @param String $s
+ * @param String $p
+ * @return Boolean
*/
-
function isMatch($s, $p) {
$m = strlen($s);
$n = strlen($p);
- $dp = array_fill(0, $m + 1, array_fill(0, $n + 1, false));
- $dp[0][0] = true;
-
- for ($j = 1; $j <= $n; $j++) {
- if ($p[$j - 1] == '*') {
- $dp[0][$j] = $dp[0][$j - 2];
- }
- }
+ $f = array_fill(0, $m + 1, array_fill(0, $n + 1, false));
+ $f[0][0] = true;
- for ($i = 1; $i <= $m; $i++) {
+ for ($i = 0; $i <= $m; $i++) {
for ($j = 1; $j <= $n; $j++) {
- if ($p[$j - 1] == '.' || $p[$j - 1] == $s[$i - 1]) {
- $dp[$i][$j] = $dp[$i - 1][$j - 1];
- } elseif ($p[$j - 1] == '*') {
- $dp[$i][$j] = $dp[$i][$j - 2];
- if ($p[$j - 2] == '.' || $p[$j - 2] == $s[$i - 1]) {
- $dp[$i][$j] = $dp[$i][$j] || $dp[$i - 1][$j];
+ if ($p[$j - 1] == '*') {
+ $f[$i][$j] = $f[$i][$j - 2];
+ if ($i > 0 && ($p[$j - 2] == '.' || $p[$j - 2] == $s[$i - 1])) {
+ $f[$i][$j] = $f[$i][$j] || $f[$i - 1][$j];
}
- } else {
- $dp[$i][$j] = false;
+ } elseif ($i > 0 && ($p[$j - 1] == '.' || $p[$j - 1] == $s[$i - 1])) {
+ $f[$i][$j] = $f[$i - 1][$j - 1];
}
}
}
- return $dp[$m][$n];
+ return $f[$m][$n];
}
}
```
+#### C
+
+```c
+bool isMatch(char* s, char* p) {
+ int m = strlen(s), n = strlen(p);
+ bool f[m + 1][n + 1];
+ memset(f, 0, sizeof(f));
+ f[0][0] = true;
+
+ for (int i = 0; i <= m; ++i) {
+ for (int j = 1; j <= n; ++j) {
+ if (p[j - 1] == '*') {
+ f[i][j] = f[i][j - 2];
+ if (i > 0 && (p[j - 2] == '.' || p[j - 2] == s[i - 1])) {
+ f[i][j] = f[i][j] || f[i - 1][j];
+ }
+ } else if (i > 0 && (p[j - 1] == '.' || p[j - 1] == s[i - 1])) {
+ f[i][j] = f[i - 1][j - 1];
+ }
+ }
+ }
+ return f[m][n];
+}
+```
+
diff --git a/solution/0000-0099/0010.Regular Expression Matching/Solution.c b/solution/0000-0099/0010.Regular Expression Matching/Solution.c
new file mode 100644
index 0000000000000..db0116921230e
--- /dev/null
+++ b/solution/0000-0099/0010.Regular Expression Matching/Solution.c
@@ -0,0 +1,33 @@
+#define MAX_LEN 1000
+
+char *ss, *pp;
+int m, n;
+int f[MAX_LEN + 1][MAX_LEN + 1];
+
+bool dfs(int i, int j) {
+ if (j >= n) {
+ return i == m;
+ }
+ if (f[i][j] != 0) {
+ return f[i][j] == 1;
+ }
+ int res = -1;
+ if (j + 1 < n && pp[j + 1] == '*') {
+ if (dfs(i, j + 2) || (i < m && (ss[i] == pp[j] || pp[j] == '.') && dfs(i + 1, j))) {
+ res = 1;
+ }
+ } else if (i < m && (ss[i] == pp[j] || pp[j] == '.') && dfs(i + 1, j + 1)) {
+ res = 1;
+ }
+ f[i][j] = res;
+ return res == 1;
+}
+
+bool isMatch(char* s, char* p) {
+ ss = s;
+ pp = p;
+ m = strlen(s);
+ n = strlen(p);
+ memset(f, 0, sizeof(f));
+ return dfs(0, 0);
+}
diff --git a/solution/0000-0099/0010.Regular Expression Matching/Solution.php b/solution/0000-0099/0010.Regular Expression Matching/Solution.php
index 85a7f34fe75da..fc9aca3447ffe 100644
--- a/solution/0000-0099/0010.Regular Expression Matching/Solution.php
+++ b/solution/0000-0099/0010.Regular Expression Matching/Solution.php
@@ -1,38 +1,36 @@
class Solution {
/**
- * @param string $s
- * @param string $p
- * @return boolean
+ * @param String $s
+ * @param String $p
+ * @return Boolean
*/
-
function isMatch($s, $p) {
$m = strlen($s);
$n = strlen($p);
+ $f = array_fill(0, $m + 1, array_fill(0, $n + 1, 0));
- $dp = array_fill(0, $m + 1, array_fill(0, $n + 1, false));
- $dp[0][0] = true;
-
- for ($j = 1; $j <= $n; $j++) {
- if ($p[$j - 1] == '*') {
- $dp[0][$j] = $dp[0][$j - 2];
+ $dfs = function ($i, $j) use (&$s, &$p, $m, $n, &$f, &$dfs) {
+ if ($j >= $n) {
+ return $i == $m;
}
- }
-
- for ($i = 1; $i <= $m; $i++) {
- for ($j = 1; $j <= $n; $j++) {
- if ($p[$j - 1] == '.' || $p[$j - 1] == $s[$i - 1]) {
- $dp[$i][$j] = $dp[$i - 1][$j - 1];
- } elseif ($p[$j - 1] == '*') {
- $dp[$i][$j] = $dp[$i][$j - 2];
- if ($p[$j - 2] == '.' || $p[$j - 2] == $s[$i - 1]) {
- $dp[$i][$j] = $dp[$i][$j] || $dp[$i - 1][$j];
- }
- } else {
- $dp[$i][$j] = false;
+ if ($f[$i][$j] != 0) {
+ return $f[$i][$j] == 1;
+ }
+ $res = -1;
+ if ($j + 1 < $n && $p[$j + 1] == '*') {
+ if (
+ $dfs($i, $j + 2) ||
+ ($i < $m && ($s[$i] == $p[$j] || $p[$j] == '.') && $dfs($i + 1, $j))
+ ) {
+ $res = 1;
}
+ } elseif ($i < $m && ($s[$i] == $p[$j] || $p[$j] == '.') && $dfs($i + 1, $j + 1)) {
+ $res = 1;
}
- }
+ $f[$i][$j] = $res;
+ return $res == 1;
+ };
- return $dp[$m][$n];
+ return $dfs(0, 0);
}
-}
+}
\ No newline at end of file
diff --git a/solution/0000-0099/0010.Regular Expression Matching/Solution2.c b/solution/0000-0099/0010.Regular Expression Matching/Solution2.c
new file mode 100644
index 0000000000000..9240063d8bd6a
--- /dev/null
+++ b/solution/0000-0099/0010.Regular Expression Matching/Solution2.c
@@ -0,0 +1,20 @@
+bool isMatch(char* s, char* p) {
+ int m = strlen(s), n = strlen(p);
+ bool f[m + 1][n + 1];
+ memset(f, 0, sizeof(f));
+ f[0][0] = true;
+
+ for (int i = 0; i <= m; ++i) {
+ for (int j = 1; j <= n; ++j) {
+ if (p[j - 1] == '*') {
+ f[i][j] = f[i][j - 2];
+ if (i > 0 && (p[j - 2] == '.' || p[j - 2] == s[i - 1])) {
+ f[i][j] = f[i][j] || f[i - 1][j];
+ }
+ } else if (i > 0 && (p[j - 1] == '.' || p[j - 1] == s[i - 1])) {
+ f[i][j] = f[i - 1][j - 1];
+ }
+ }
+ }
+ return f[m][n];
+}
diff --git a/solution/0000-0099/0010.Regular Expression Matching/Solution2.php b/solution/0000-0099/0010.Regular Expression Matching/Solution2.php
new file mode 100644
index 0000000000000..6f40295f7f06c
--- /dev/null
+++ b/solution/0000-0099/0010.Regular Expression Matching/Solution2.php
@@ -0,0 +1,29 @@
+class Solution {
+ /**
+ * @param String $s
+ * @param String $p
+ * @return Boolean
+ */
+ function isMatch($s, $p) {
+ $m = strlen($s);
+ $n = strlen($p);
+
+ $f = array_fill(0, $m + 1, array_fill(0, $n + 1, false));
+ $f[0][0] = true;
+
+ for ($i = 0; $i <= $m; $i++) {
+ for ($j = 1; $j <= $n; $j++) {
+ if ($p[$j - 1] == '*') {
+ $f[$i][$j] = $f[$i][$j - 2];
+ if ($i > 0 && ($p[$j - 2] == '.' || $p[$j - 2] == $s[$i - 1])) {
+ $f[$i][$j] = $f[$i][$j] || $f[$i - 1][$j];
+ }
+ } elseif ($i > 0 && ($p[$j - 1] == '.' || $p[$j - 1] == $s[$i - 1])) {
+ $f[$i][$j] = $f[$i - 1][$j - 1];
+ }
+ }
+ }
+
+ return $f[$m][$n];
+ }
+}
\ No newline at end of file
diff --git a/solution/0000-0099/0011.Container With Most Water/README.md b/solution/0000-0099/0011.Container With Most Water/README.md
index 1a3de695501d6..70c5128220e2c 100644
--- a/solution/0000-0099/0011.Container With Most Water/README.md
+++ b/solution/0000-0099/0011.Container With Most Water/README.md
@@ -262,6 +262,33 @@ class Solution {
}
```
+#### C
+
+```c
+int min(int a, int b) {
+ return a < b ? a : b;
+}
+
+int max(int a, int b) {
+ return a > b ? a : b;
+}
+
+int maxArea(int* height, int heightSize) {
+ int l = 0, r = heightSize - 1;
+ int ans = 0;
+ while (l < r) {
+ int t = min(height[l], height[r]) * (r - l);
+ ans = max(ans, t);
+ if (height[l] < height[r]) {
+ ++l;
+ } else {
+ --r;
+ }
+ }
+ return ans;
+}
+```
+
diff --git a/solution/0000-0099/0011.Container With Most Water/README_EN.md b/solution/0000-0099/0011.Container With Most Water/README_EN.md
index 5d113a38fbc66..0a0ab8c8f7108 100644
--- a/solution/0000-0099/0011.Container With Most Water/README_EN.md
+++ b/solution/0000-0099/0011.Container With Most Water/README_EN.md
@@ -259,6 +259,33 @@ class Solution {
}
```
+#### C
+
+```c
+int min(int a, int b) {
+ return a < b ? a : b;
+}
+
+int max(int a, int b) {
+ return a > b ? a : b;
+}
+
+int maxArea(int* height, int heightSize) {
+ int l = 0, r = heightSize - 1;
+ int ans = 0;
+ while (l < r) {
+ int t = min(height[l], height[r]) * (r - l);
+ ans = max(ans, t);
+ if (height[l] < height[r]) {
+ ++l;
+ } else {
+ --r;
+ }
+ }
+ return ans;
+}
+```
+
diff --git a/solution/0000-0099/0011.Container With Most Water/Solution.c b/solution/0000-0099/0011.Container With Most Water/Solution.c
new file mode 100644
index 0000000000000..a2dd45e5b194d
--- /dev/null
+++ b/solution/0000-0099/0011.Container With Most Water/Solution.c
@@ -0,0 +1,22 @@
+int min(int a, int b) {
+ return a < b ? a : b;
+}
+
+int max(int a, int b) {
+ return a > b ? a : b;
+}
+
+int maxArea(int* height, int heightSize) {
+ int l = 0, r = heightSize - 1;
+ int ans = 0;
+ while (l < r) {
+ int t = min(height[l], height[r]) * (r - l);
+ ans = max(ans, t);
+ if (height[l] < height[r]) {
+ ++l;
+ } else {
+ --r;
+ }
+ }
+ return ans;
+}
diff --git a/solution/0000-0099/0012.Integer to Roman/README.md b/solution/0000-0099/0012.Integer to Roman/README.md
index 815d37edba30b..c7151c82720b4 100644
--- a/solution/0000-0099/0012.Integer to Roman/README.md
+++ b/solution/0000-0099/0012.Integer to Roman/README.md
@@ -300,6 +300,30 @@ class Solution {
}
```
+#### C
+
+```c
+static const char* cs[] = {
+ "M", "CM", "D", "CD", "C", "XC",
+ "L", "XL", "X", "IX", "V", "IV", "I"};
+
+static const int vs[] = {
+ 1000, 900, 500, 400, 100, 90,
+ 50, 40, 10, 9, 5, 4, 1};
+
+char* intToRoman(int num) {
+ static char ans[20];
+ ans[0] = '\0';
+ for (int i = 0; i < 13; ++i) {
+ while (num >= vs[i]) {
+ num -= vs[i];
+ strcat(ans, cs[i]);
+ }
+ }
+ return ans;
+}
+```
+
diff --git a/solution/0000-0099/0012.Integer to Roman/README_EN.md b/solution/0000-0099/0012.Integer to Roman/README_EN.md
index c7b57f780c463..9fcb12b9a56d2 100644
--- a/solution/0000-0099/0012.Integer to Roman/README_EN.md
+++ b/solution/0000-0099/0012.Integer to Roman/README_EN.md
@@ -298,6 +298,30 @@ class Solution {
}
```
+#### C
+
+```c
+static const char* cs[] = {
+ "M", "CM", "D", "CD", "C", "XC",
+ "L", "XL", "X", "IX", "V", "IV", "I"};
+
+static const int vs[] = {
+ 1000, 900, 500, 400, 100, 90,
+ 50, 40, 10, 9, 5, 4, 1};
+
+char* intToRoman(int num) {
+ static char ans[20];
+ ans[0] = '\0';
+ for (int i = 0; i < 13; ++i) {
+ while (num >= vs[i]) {
+ num -= vs[i];
+ strcat(ans, cs[i]);
+ }
+ }
+ return ans;
+}
+```
+
diff --git a/solution/0000-0099/0012.Integer to Roman/Solution.c b/solution/0000-0099/0012.Integer to Roman/Solution.c
new file mode 100644
index 0000000000000..1417b40e44318
--- /dev/null
+++ b/solution/0000-0099/0012.Integer to Roman/Solution.c
@@ -0,0 +1,19 @@
+static const char* cs[] = {
+ "M", "CM", "D", "CD", "C", "XC",
+ "L", "XL", "X", "IX", "V", "IV", "I"};
+
+static const int vs[] = {
+ 1000, 900, 500, 400, 100, 90,
+ 50, 40, 10, 9, 5, 4, 1};
+
+char* intToRoman(int num) {
+ static char ans[20];
+ ans[0] = '\0';
+ for (int i = 0; i < 13; ++i) {
+ while (num >= vs[i]) {
+ num -= vs[i];
+ strcat(ans, cs[i]);
+ }
+ }
+ return ans;
+}
diff --git a/solution/0000-0099/0013.Roman to Integer/README.md b/solution/0000-0099/0013.Roman to Integer/README.md
index 4d985955579f8..604ebaaf5c8e8 100644
--- a/solution/0000-0099/0013.Roman to Integer/README.md
+++ b/solution/0000-0099/0013.Roman to Integer/README.md
@@ -341,6 +341,32 @@ def roman_to_int(s)
end
```
+#### C
+
+```c
+int nums(char c) {
+ switch (c) {
+ case 'I': return 1;
+ case 'V': return 5;
+ case 'X': return 10;
+ case 'L': return 50;
+ case 'C': return 100;
+ case 'D': return 500;
+ case 'M': return 1000;
+ default: return 0;
+ }
+}
+
+int romanToInt(char* s) {
+ int ans = nums(s[strlen(s) - 1]);
+ for (int i = 0; i < (int) strlen(s) - 1; ++i) {
+ int sign = nums(s[i]) < nums(s[i + 1]) ? -1 : 1;
+ ans += sign * nums(s[i]);
+ }
+ return ans;
+}
+```
+
diff --git a/solution/0000-0099/0013.Roman to Integer/README_EN.md b/solution/0000-0099/0013.Roman to Integer/README_EN.md
index 099ed325658a3..5d93d580a88f1 100644
--- a/solution/0000-0099/0013.Roman to Integer/README_EN.md
+++ b/solution/0000-0099/0013.Roman to Integer/README_EN.md
@@ -327,6 +327,32 @@ def roman_to_int(s)
end
```
+#### C
+
+```c
+int nums(char c) {
+ switch (c) {
+ case 'I': return 1;
+ case 'V': return 5;
+ case 'X': return 10;
+ case 'L': return 50;
+ case 'C': return 100;
+ case 'D': return 500;
+ case 'M': return 1000;
+ default: return 0;
+ }
+}
+
+int romanToInt(char* s) {
+ int ans = nums(s[strlen(s) - 1]);
+ for (int i = 0; i < (int) strlen(s) - 1; ++i) {
+ int sign = nums(s[i]) < nums(s[i + 1]) ? -1 : 1;
+ ans += sign * nums(s[i]);
+ }
+ return ans;
+}
+```
+
diff --git a/solution/0000-0099/0013.Roman to Integer/Solution.c b/solution/0000-0099/0013.Roman to Integer/Solution.c
new file mode 100644
index 0000000000000..7e3199c1e1fa7
--- /dev/null
+++ b/solution/0000-0099/0013.Roman to Integer/Solution.c
@@ -0,0 +1,21 @@
+int nums(char c) {
+ switch (c) {
+ case 'I': return 1;
+ case 'V': return 5;
+ case 'X': return 10;
+ case 'L': return 50;
+ case 'C': return 100;
+ case 'D': return 500;
+ case 'M': return 1000;
+ default: return 0;
+ }
+}
+
+int romanToInt(char* s) {
+ int ans = nums(s[strlen(s) - 1]);
+ for (int i = 0; i < (int) strlen(s) - 1; ++i) {
+ int sign = nums(s[i]) < nums(s[i + 1]) ? -1 : 1;
+ ans += sign * nums(s[i]);
+ }
+ return ans;
+}
diff --git a/solution/0000-0099/0014.Longest Common Prefix/README.md b/solution/0000-0099/0014.Longest Common Prefix/README.md
index 5f3529f01eb2c..fceadc76296da 100644
--- a/solution/0000-0099/0014.Longest Common Prefix/README.md
+++ b/solution/0000-0099/0014.Longest Common Prefix/README.md
@@ -4,6 +4,7 @@ difficulty: 简单
edit_url: https://github.com/doocs/leetcode/edit/main/solution/0000-0099/0014.Longest%20Common%20Prefix/README.md
tags:
- 字典树
+ - 数组
- 字符串
---
@@ -251,6 +252,22 @@ def longest_common_prefix(strs)
end
```
+#### C
+
+```c
+char* longestCommonPrefix(char** strs, int strsSize) {
+ for (int i = 0; strs[0][i]; i++) {
+ for (int j = 1; j < strsSize; j++) {
+ if (strs[j][i] != strs[0][i]) {
+ strs[0][i] = '\0';
+ return strs[0];
+ }
+ }
+ }
+ return strs[0];
+}
+```
+
diff --git a/solution/0000-0099/0014.Longest Common Prefix/README_EN.md b/solution/0000-0099/0014.Longest Common Prefix/README_EN.md
index 32b3183c65f1b..0002faebd0c27 100644
--- a/solution/0000-0099/0014.Longest Common Prefix/README_EN.md
+++ b/solution/0000-0099/0014.Longest Common Prefix/README_EN.md
@@ -4,6 +4,7 @@ difficulty: Easy
edit_url: https://github.com/doocs/leetcode/edit/main/solution/0000-0099/0014.Longest%20Common%20Prefix/README_EN.md
tags:
- Trie
+ - Array
- String
---
@@ -250,6 +251,22 @@ def longest_common_prefix(strs)
end
```
+#### C
+
+```c
+char* longestCommonPrefix(char** strs, int strsSize) {
+ for (int i = 0; strs[0][i]; i++) {
+ for (int j = 1; j < strsSize; j++) {
+ if (strs[j][i] != strs[0][i]) {
+ strs[0][i] = '\0';
+ return strs[0];
+ }
+ }
+ }
+ return strs[0];
+}
+```
+
diff --git a/solution/0000-0099/0014.Longest Common Prefix/Solution.c b/solution/0000-0099/0014.Longest Common Prefix/Solution.c
new file mode 100644
index 0000000000000..5302a586083f1
--- /dev/null
+++ b/solution/0000-0099/0014.Longest Common Prefix/Solution.c
@@ -0,0 +1,11 @@
+char* longestCommonPrefix(char** strs, int strsSize) {
+ for (int i = 0; strs[0][i]; i++) {
+ for (int j = 1; j < strsSize; j++) {
+ if (strs[j][i] != strs[0][i]) {
+ strs[0][i] = '\0';
+ return strs[0];
+ }
+ }
+ }
+ return strs[0];
+}
diff --git a/solution/0000-0099/0015.3Sum/README.md b/solution/0000-0099/0015.3Sum/README.md
index 97e493065a58f..d38db88f5d3b1 100644
--- a/solution/0000-0099/0015.3Sum/README.md
+++ b/solution/0000-0099/0015.3Sum/README.md
@@ -453,6 +453,54 @@ class Solution {
}
```
+#### C
+
+```c
+int cmp(const void* a, const void* b) {
+ return *(int*) a - *(int*) b;
+}
+
+int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) {
+ *returnSize = 0;
+ int cap = 1000;
+ int** ans = (int**) malloc(sizeof(int*) * cap);
+ *returnColumnSizes = (int*) malloc(sizeof(int) * cap);
+
+ qsort(nums, numsSize, sizeof(int), cmp);
+
+ for (int i = 0; i < numsSize - 2 && nums[i] <= 0; ++i) {
+ if (i > 0 && nums[i] == nums[i - 1]) continue;
+ int j = i + 1, k = numsSize - 1;
+ while (j < k) {
+ int sum = nums[i] + nums[j] + nums[k];
+ if (sum < 0) {
+ ++j;
+ } else if (sum > 0) {
+ --k;
+ } else {
+ if (*returnSize >= cap) {
+ cap *= 2;
+ ans = (int**) realloc(ans, sizeof(int*) * cap);
+ *returnColumnSizes = (int*) realloc(*returnColumnSizes, sizeof(int) * cap);
+ }
+ ans[*returnSize] = (int*) malloc(sizeof(int) * 3);
+ ans[*returnSize][0] = nums[i];
+ ans[*returnSize][1] = nums[j];
+ ans[*returnSize][2] = nums[k];
+ (*returnColumnSizes)[*returnSize] = 3;
+ (*returnSize)++;
+
+ ++j;
+ --k;
+ while (j < k && nums[j] == nums[j - 1]) ++j;
+ while (j < k && nums[k] == nums[k + 1]) --k;
+ }
+ }
+ }
+ return ans;
+}
+```
+
diff --git a/solution/0000-0099/0015.3Sum/README_EN.md b/solution/0000-0099/0015.3Sum/README_EN.md
index 9f84f4eceb78f..800479adb0a06 100644
--- a/solution/0000-0099/0015.3Sum/README_EN.md
+++ b/solution/0000-0099/0015.3Sum/README_EN.md
@@ -449,6 +449,54 @@ class Solution {
}
```
+#### C
+
+```c
+int cmp(const void* a, const void* b) {
+ return *(int*) a - *(int*) b;
+}
+
+int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) {
+ *returnSize = 0;
+ int cap = 1000;
+ int** ans = (int**) malloc(sizeof(int*) * cap);
+ *returnColumnSizes = (int*) malloc(sizeof(int) * cap);
+
+ qsort(nums, numsSize, sizeof(int), cmp);
+
+ for (int i = 0; i < numsSize - 2 && nums[i] <= 0; ++i) {
+ if (i > 0 && nums[i] == nums[i - 1]) continue;
+ int j = i + 1, k = numsSize - 1;
+ while (j < k) {
+ int sum = nums[i] + nums[j] + nums[k];
+ if (sum < 0) {
+ ++j;
+ } else if (sum > 0) {
+ --k;
+ } else {
+ if (*returnSize >= cap) {
+ cap *= 2;
+ ans = (int**) realloc(ans, sizeof(int*) * cap);
+ *returnColumnSizes = (int*) realloc(*returnColumnSizes, sizeof(int) * cap);
+ }
+ ans[*returnSize] = (int*) malloc(sizeof(int) * 3);
+ ans[*returnSize][0] = nums[i];
+ ans[*returnSize][1] = nums[j];
+ ans[*returnSize][2] = nums[k];
+ (*returnColumnSizes)[*returnSize] = 3;
+ (*returnSize)++;
+
+ ++j;
+ --k;
+ while (j < k && nums[j] == nums[j - 1]) ++j;
+ while (j < k && nums[k] == nums[k + 1]) --k;
+ }
+ }
+ }
+ return ans;
+}
+```
+
diff --git a/solution/0000-0099/0015.3Sum/Solution.c b/solution/0000-0099/0015.3Sum/Solution.c
new file mode 100644
index 0000000000000..cce897d4a81cd
--- /dev/null
+++ b/solution/0000-0099/0015.3Sum/Solution.c
@@ -0,0 +1,43 @@
+int cmp(const void* a, const void* b) {
+ return *(int*) a - *(int*) b;
+}
+
+int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) {
+ *returnSize = 0;
+ int cap = 1000;
+ int** ans = (int**) malloc(sizeof(int*) * cap);
+ *returnColumnSizes = (int*) malloc(sizeof(int) * cap);
+
+ qsort(nums, numsSize, sizeof(int), cmp);
+
+ for (int i = 0; i < numsSize - 2 && nums[i] <= 0; ++i) {
+ if (i > 0 && nums[i] == nums[i - 1]) continue;
+ int j = i + 1, k = numsSize - 1;
+ while (j < k) {
+ int sum = nums[i] + nums[j] + nums[k];
+ if (sum < 0) {
+ ++j;
+ } else if (sum > 0) {
+ --k;
+ } else {
+ if (*returnSize >= cap) {
+ cap *= 2;
+ ans = (int**) realloc(ans, sizeof(int*) * cap);
+ *returnColumnSizes = (int*) realloc(*returnColumnSizes, sizeof(int) * cap);
+ }
+ ans[*returnSize] = (int*) malloc(sizeof(int) * 3);
+ ans[*returnSize][0] = nums[i];
+ ans[*returnSize][1] = nums[j];
+ ans[*returnSize][2] = nums[k];
+ (*returnColumnSizes)[*returnSize] = 3;
+ (*returnSize)++;
+
+ ++j;
+ --k;
+ while (j < k && nums[j] == nums[j - 1]) ++j;
+ while (j < k && nums[k] == nums[k + 1]) --k;
+ }
+ }
+ }
+ return ans;
+}
diff --git a/solution/0000-0099/0016.3Sum Closest/README.md b/solution/0000-0099/0016.3Sum Closest/README.md
index 406e23f70dbb9..c724790896aff 100644
--- a/solution/0000-0099/0016.3Sum Closest/README.md
+++ b/solution/0000-0099/0016.3Sum Closest/README.md
@@ -315,6 +315,37 @@ class Solution {
}
```
+#### C
+
+```c
+int cmp(const void* a, const void* b) {
+ return (*(int*) a - *(int*) b);
+}
+
+int threeSumClosest(int* nums, int numsSize, int target) {
+ qsort(nums, numsSize, sizeof(int), cmp);
+ int ans = 1 << 30;
+ for (int i = 0; i < numsSize; ++i) {
+ int j = i + 1, k = numsSize - 1;
+ while (j < k) {
+ int t = nums[i] + nums[j] + nums[k];
+ if (t == target) {
+ return t;
+ }
+ if (abs(t - target) < abs(ans - target)) {
+ ans = t;
+ }
+ if (t > target) {
+ --k;
+ } else {
+ ++j;
+ }
+ }
+ }
+ return ans;
+}
+```
+
diff --git a/solution/0000-0099/0016.3Sum Closest/README_EN.md b/solution/0000-0099/0016.3Sum Closest/README_EN.md
index b5ccdf0198cd0..3366410926aee 100644
--- a/solution/0000-0099/0016.3Sum Closest/README_EN.md
+++ b/solution/0000-0099/0016.3Sum Closest/README_EN.md
@@ -314,6 +314,37 @@ class Solution {
}
```
+#### C
+
+```c
+int cmp(const void* a, const void* b) {
+ return (*(int*) a - *(int*) b);
+}
+
+int threeSumClosest(int* nums, int numsSize, int target) {
+ qsort(nums, numsSize, sizeof(int), cmp);
+ int ans = 1 << 30;
+ for (int i = 0; i < numsSize; ++i) {
+ int j = i + 1, k = numsSize - 1;
+ while (j < k) {
+ int t = nums[i] + nums[j] + nums[k];
+ if (t == target) {
+ return t;
+ }
+ if (abs(t - target) < abs(ans - target)) {
+ ans = t;
+ }
+ if (t > target) {
+ --k;
+ } else {
+ ++j;
+ }
+ }
+ }
+ return ans;
+}
+```
+
diff --git a/solution/0000-0099/0016.3Sum Closest/Solution.c b/solution/0000-0099/0016.3Sum Closest/Solution.c
new file mode 100644
index 0000000000000..778c1a2aca594
--- /dev/null
+++ b/solution/0000-0099/0016.3Sum Closest/Solution.c
@@ -0,0 +1,26 @@
+int cmp(const void* a, const void* b) {
+ return (*(int*) a - *(int*) b);
+}
+
+int threeSumClosest(int* nums, int numsSize, int target) {
+ qsort(nums, numsSize, sizeof(int), cmp);
+ int ans = 1 << 30;
+ for (int i = 0; i < numsSize; ++i) {
+ int j = i + 1, k = numsSize - 1;
+ while (j < k) {
+ int t = nums[i] + nums[j] + nums[k];
+ if (t == target) {
+ return t;
+ }
+ if (abs(t - target) < abs(ans - target)) {
+ ans = t;
+ }
+ if (t > target) {
+ --k;
+ } else {
+ ++j;
+ }
+ }
+ }
+ return ans;
+}
diff --git a/solution/0000-0099/0017.Letter Combinations of a Phone Number/README.md b/solution/0000-0099/0017.Letter Combinations of a Phone Number/README.md
index a8ca434436f2e..6f1223d12ac1f 100644
--- a/solution/0000-0099/0017.Letter Combinations of a Phone Number/README.md
+++ b/solution/0000-0099/0017.Letter Combinations of a Phone Number/README.md
@@ -22,7 +22,7 @@ tags:
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
-
+
@@ -555,6 +555,48 @@ class Solution {
}
```
+#### C
+
+```c
+char* d[] = {"abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
+
+char** letterCombinations(char* digits, int* returnSize) {
+ if (!*digits) {
+ *returnSize = 0;
+ return NULL;
+ }
+
+ int size = 1;
+ char** ans = (char**) malloc(sizeof(char*));
+ ans[0] = strdup("");
+
+ for (int x = 0; digits[x]; ++x) {
+ char* s = d[digits[x] - '2'];
+ int len = strlen(s);
+ char** t = (char**) malloc(sizeof(char*) * size * len);
+ int tSize = 0;
+
+ for (int i = 0; i < size; ++i) {
+ for (int j = 0; j < len; ++j) {
+ int oldLen = strlen(ans[i]);
+ char* tmp = (char*) malloc(oldLen + 2);
+ strcpy(tmp, ans[i]);
+ tmp[oldLen] = s[j];
+ tmp[oldLen + 1] = '\0';
+ t[tSize++] = tmp;
+ }
+ free(ans[i]);
+ }
+ free(ans);
+ ans = t;
+ size = tSize;
+ }
+
+ *returnSize = size;
+ return ans;
+}
+```
+
diff --git a/solution/0000-0099/0017.Letter Combinations of a Phone Number/README_EN.md b/solution/0000-0099/0017.Letter Combinations of a Phone Number/README_EN.md
index ffad07737163e..dba840d7bd8ee 100644
--- a/solution/0000-0099/0017.Letter Combinations of a Phone Number/README_EN.md
+++ b/solution/0000-0099/0017.Letter Combinations of a Phone Number/README_EN.md
@@ -551,6 +551,48 @@ class Solution {
}
```
+#### C
+
+```c
+char* d[] = {"abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
+
+char** letterCombinations(char* digits, int* returnSize) {
+ if (!*digits) {
+ *returnSize = 0;
+ return NULL;
+ }
+
+ int size = 1;
+ char** ans = (char**) malloc(sizeof(char*));
+ ans[0] = strdup("");
+
+ for (int x = 0; digits[x]; ++x) {
+ char* s = d[digits[x] - '2'];
+ int len = strlen(s);
+ char** t = (char**) malloc(sizeof(char*) * size * len);
+ int tSize = 0;
+
+ for (int i = 0; i < size; ++i) {
+ for (int j = 0; j < len; ++j) {
+ int oldLen = strlen(ans[i]);
+ char* tmp = (char*) malloc(oldLen + 2);
+ strcpy(tmp, ans[i]);
+ tmp[oldLen] = s[j];
+ tmp[oldLen + 1] = '\0';
+ t[tSize++] = tmp;
+ }
+ free(ans[i]);
+ }
+ free(ans);
+ ans = t;
+ size = tSize;
+ }
+
+ *returnSize = size;
+ return ans;
+}
+```
+
diff --git a/solution/0000-0099/0017.Letter Combinations of a Phone Number/Solution.c b/solution/0000-0099/0017.Letter Combinations of a Phone Number/Solution.c
new file mode 100644
index 0000000000000..e02c971a3a8c6
--- /dev/null
+++ b/solution/0000-0099/0017.Letter Combinations of a Phone Number/Solution.c
@@ -0,0 +1,37 @@
+char* d[] = {"abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
+
+char** letterCombinations(char* digits, int* returnSize) {
+ if (!*digits) {
+ *returnSize = 0;
+ return NULL;
+ }
+
+ int size = 1;
+ char** ans = (char**) malloc(sizeof(char*));
+ ans[0] = strdup("");
+
+ for (int x = 0; digits[x]; ++x) {
+ char* s = d[digits[x] - '2'];
+ int len = strlen(s);
+ char** t = (char**) malloc(sizeof(char*) * size * len);
+ int tSize = 0;
+
+ for (int i = 0; i < size; ++i) {
+ for (int j = 0; j < len; ++j) {
+ int oldLen = strlen(ans[i]);
+ char* tmp = (char*) malloc(oldLen + 2);
+ strcpy(tmp, ans[i]);
+ tmp[oldLen] = s[j];
+ tmp[oldLen + 1] = '\0';
+ t[tSize++] = tmp;
+ }
+ free(ans[i]);
+ }
+ free(ans);
+ ans = t;
+ size = tSize;
+ }
+
+ *returnSize = size;
+ return ans;
+}
diff --git a/solution/0000-0099/0017.Letter Combinations of a Phone Number/images/1200px-telephone-keypad2svg.png b/solution/0000-0099/0017.Letter Combinations of a Phone Number/images/1200px-telephone-keypad2svg.png
new file mode 100644
index 0000000000000..cbf69ae96598d
Binary files /dev/null and b/solution/0000-0099/0017.Letter Combinations of a Phone Number/images/1200px-telephone-keypad2svg.png differ
diff --git a/solution/0000-0099/0017.Letter Combinations of a Phone Number/images/1752723054-mfIHZs-image.png b/solution/0000-0099/0017.Letter Combinations of a Phone Number/images/1752723054-mfIHZs-image.png
new file mode 100644
index 0000000000000..e4d9a76bfe05c
Binary files /dev/null and b/solution/0000-0099/0017.Letter Combinations of a Phone Number/images/1752723054-mfIHZs-image.png differ
diff --git a/solution/0000-0099/0017.Letter Combinations of a Phone Number/images/17_telephone_keypad.png b/solution/0000-0099/0017.Letter Combinations of a Phone Number/images/17_telephone_keypad.png
deleted file mode 100644
index ef7a0bffee3e2..0000000000000
Binary files a/solution/0000-0099/0017.Letter Combinations of a Phone Number/images/17_telephone_keypad.png and /dev/null differ
diff --git a/solution/0000-0099/0017.Letter Combinations of a Phone Number/images/200px-Telephone-keypad2.svg.png b/solution/0000-0099/0017.Letter Combinations of a Phone Number/images/200px-Telephone-keypad2.svg.png
deleted file mode 100644
index 38764028d1835..0000000000000
Binary files a/solution/0000-0099/0017.Letter Combinations of a Phone Number/images/200px-Telephone-keypad2.svg.png and /dev/null differ
diff --git a/solution/0000-0099/0017.Letter Combinations of a Phone Number/images/200px-telephone-keypad2svg.png b/solution/0000-0099/0017.Letter Combinations of a Phone Number/images/200px-telephone-keypad2svg.png
deleted file mode 100644
index 38764028d1835..0000000000000
Binary files a/solution/0000-0099/0017.Letter Combinations of a Phone Number/images/200px-telephone-keypad2svg.png and /dev/null differ
diff --git a/solution/0000-0099/0020.Valid Parentheses/README.md b/solution/0000-0099/0020.Valid Parentheses/README.md
index e4c364fe798a6..d09f9eda8a015 100644
--- a/solution/0000-0099/0020.Valid Parentheses/README.md
+++ b/solution/0000-0099/0020.Valid Parentheses/README.md
@@ -61,6 +61,14 @@ tags:
输出:true
+示例 5:
+
+
+
输入:s = "([)]"
+
+
输出:false
+
+
提示:
diff --git a/solution/0000-0099/0020.Valid Parentheses/README_EN.md b/solution/0000-0099/0020.Valid Parentheses/README_EN.md
index cf0fc8a16deba..24c94a545cabb 100644
--- a/solution/0000-0099/0020.Valid Parentheses/README_EN.md
+++ b/solution/0000-0099/0020.Valid Parentheses/README_EN.md
@@ -60,6 +60,14 @@ tags:
Output: true
+Example 5:
+
+
+
Input: s = "([)]"
+
+
Output: false
+
+
Constraints:
diff --git a/solution/0000-0099/0023.Merge k Sorted Lists/README_EN.md b/solution/0000-0099/0023.Merge k Sorted Lists/README_EN.md
index e7e07e00330c5..787342715e2e0 100644
--- a/solution/0000-0099/0023.Merge k Sorted Lists/README_EN.md
+++ b/solution/0000-0099/0023.Merge k Sorted Lists/README_EN.md
@@ -35,7 +35,7 @@ tags:
1->3->4,
2->6
]
-merging them into one sorted list:
+merging them into one sorted linked list:
1->1->2->3->4->4->5->6
diff --git a/solution/0000-0099/0032.Longest Valid Parentheses/README.md b/solution/0000-0099/0032.Longest Valid Parentheses/README.md
index 41b8be83eb9e6..6e23e7719174d 100644
--- a/solution/0000-0099/0032.Longest Valid Parentheses/README.md
+++ b/solution/0000-0099/0032.Longest Valid Parentheses/README.md
@@ -18,7 +18,9 @@ tags:
-给你一个只包含 '('
和 ')'
的字符串,找出最长有效(格式正确且连续)括号子串的长度。
+给你一个只包含 '('
和 ')'
的字符串,找出最长有效(格式正确且连续)括号 子串 的长度。
+
+左右括号匹配,即每个左括号都有对应的右括号将其闭合的字符串是格式正确的,比如 "(()())"
。
diff --git a/solution/0000-0099/0033.Search in Rotated Sorted Array/README.md b/solution/0000-0099/0033.Search in Rotated Sorted Array/README.md
index d84ddc3e91a90..055329f700460 100644
--- a/solution/0000-0099/0033.Search in Rotated Sorted Array/README.md
+++ b/solution/0000-0099/0033.Search in Rotated Sorted Array/README.md
@@ -19,7 +19,7 @@ tags:
整数数组 nums
按升序排列,数组中的值 互不相同 。
-在传递给函数之前,nums
在预先未知的某个下标 k
(0 <= k < nums.length
)上进行了 旋转,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]]
(下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7]
在下标 3
处经旋转后可能变为 [4,5,6,7,0,1,2]
。
+在传递给函数之前,nums
在预先未知的某个下标 k
(0 <= k < nums.length
)上进行了 旋转,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]]
(下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7]
向左旋转 3
次后可能变为 [4,5,6,7,0,1,2]
。
给你 旋转后 的数组 nums
和一个整数 target
,如果 nums
中存在这个目标值 target
,则返回它的下标,否则返回 -1
。
diff --git a/solution/0000-0099/0033.Search in Rotated Sorted Array/README_EN.md b/solution/0000-0099/0033.Search in Rotated Sorted Array/README_EN.md
index 871221d1251a8..ff3c0a1ead08a 100644
--- a/solution/0000-0099/0033.Search in Rotated Sorted Array/README_EN.md
+++ b/solution/0000-0099/0033.Search in Rotated Sorted Array/README_EN.md
@@ -19,7 +19,7 @@ tags:
There is an integer array nums
sorted in ascending order (with distinct values).
-Prior to being passed to your function, nums
is possibly rotated at an unknown pivot index k
(1 <= k < nums.length
) such that the resulting array is [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]]
(0-indexed). For example, [0,1,2,4,5,6,7]
might be rotated at pivot index 3
and become [4,5,6,7,0,1,2]
.
+Prior to being passed to your function, nums
is possibly left rotated at an unknown index k
(1 <= k < nums.length
) such that the resulting array is [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]]
(0-indexed). For example, [0,1,2,4,5,6,7]
might be left rotated by 3
indices and become [4,5,6,7,0,1,2]
.
Given the array nums
after the possible rotation and an integer target
, return the index of target
if it is in nums
, or -1
if it is not in nums
.
diff --git a/solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/README.md b/solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/README.md
index 361728caaea79..30c5a25b9f808 100644
--- a/solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/README.md
+++ b/solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/README.md
@@ -211,6 +211,31 @@ var searchRange = function (nums, target) {
};
```
+#### C#
+
+```cs
+public class Solution {
+ public int[] SearchRange(int[] nums, int target) {
+ int l = Search(nums, target);
+ int r = Search(nums, target + 1);
+ return l == r ? new int[] {-1, -1} : new int[] {l, r - 1};
+ }
+
+ private int Search(int[] nums, int x) {
+ int left = 0, right = nums.Length;
+ while (left < right) {
+ int mid = (left + right) >>> 1;
+ if (nums[mid] >= x) {
+ right = mid;
+ } else {
+ left = mid + 1;
+ }
+ }
+ return left;
+ }
+}
+```
+
#### PHP
```php
diff --git a/solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/README_EN.md b/solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/README_EN.md
index 491b8072d5031..2458ddc9bbc57 100644
--- a/solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/README_EN.md
+++ b/solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/README_EN.md
@@ -201,6 +201,31 @@ var searchRange = function (nums, target) {
};
```
+#### C#
+
+```cs
+public class Solution {
+ public int[] SearchRange(int[] nums, int target) {
+ int l = Search(nums, target);
+ int r = Search(nums, target + 1);
+ return l == r ? new int[] {-1, -1} : new int[] {l, r - 1};
+ }
+
+ private int Search(int[] nums, int x) {
+ int left = 0, right = nums.Length;
+ while (left < right) {
+ int mid = (left + right) >>> 1;
+ if (nums[mid] >= x) {
+ right = mid;
+ } else {
+ left = mid + 1;
+ }
+ }
+ return left;
+ }
+}
+```
+
#### PHP
```php
diff --git a/solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/Solution.cs b/solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/Solution.cs
new file mode 100644
index 0000000000000..b934d4277e689
--- /dev/null
+++ b/solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/Solution.cs
@@ -0,0 +1,20 @@
+public class Solution {
+ public int[] SearchRange(int[] nums, int target) {
+ int l = Search(nums, target);
+ int r = Search(nums, target + 1);
+ return l == r ? new int[] {-1, -1} : new int[] {l, r - 1};
+ }
+
+ private int Search(int[] nums, int x) {
+ int left = 0, right = nums.Length;
+ while (left < right) {
+ int mid = (left + right) >>> 1;
+ if (nums[mid] >= x) {
+ right = mid;
+ } else {
+ left = mid + 1;
+ }
+ }
+ return left;
+ }
+}
\ No newline at end of file
diff --git a/solution/0000-0099/0045.Jump Game II/README.md b/solution/0000-0099/0045.Jump Game II/README.md
index df5afce25a020..89be5cab7bfd5 100644
--- a/solution/0000-0099/0045.Jump Game II/README.md
+++ b/solution/0000-0099/0045.Jump Game II/README.md
@@ -20,14 +20,14 @@ tags:
给定一个长度为 n
的 0 索引整数数组 nums
。初始位置为 nums[0]
。
-每个元素 nums[i]
表示从索引 i
向后跳转的最大长度。换句话说,如果你在 nums[i]
处,你可以跳转到任意 nums[i + j]
处:
+每个元素 nums[i]
表示从索引 i
向后跳转的最大长度。换句话说,如果你在索引 i
处,你可以跳转到任意 (i + j)
处:
- 0 <= j <= nums[i]
+ 0 <= j <= nums[i]
且
i + j < n
-返回到达 nums[n - 1]
的最小跳跃次数。生成的测试用例可以到达 nums[n - 1]
。
+返回到达 n - 1
的最小跳跃次数。测试用例保证可以到达 n - 1
。
@@ -54,7 +54,7 @@ tags:
1 <= nums.length <= 104
0 <= nums[i] <= 1000
- - 题目保证可以到达
nums[n-1]
+ - 题目保证可以到达
n - 1
diff --git a/solution/0000-0099/0045.Jump Game II/README_EN.md b/solution/0000-0099/0045.Jump Game II/README_EN.md
index 26a6b6242448f..d1f1c273a53a4 100644
--- a/solution/0000-0099/0045.Jump Game II/README_EN.md
+++ b/solution/0000-0099/0045.Jump Game II/README_EN.md
@@ -18,16 +18,16 @@ tags:
-You are given a 0-indexed array of integers nums
of length n
. You are initially positioned at nums[0]
.
+You are given a 0-indexed array of integers nums
of length n
. You are initially positioned at index 0.
-Each element nums[i]
represents the maximum length of a forward jump from index i
. In other words, if you are at nums[i]
, you can jump to any nums[i + j]
where:
+Each element nums[i]
represents the maximum length of a forward jump from index i
. In other words, if you are at index i
, you can jump to any index (i + j)
where:
0 <= j <= nums[i]
and
i + j < n
-Return the minimum number of jumps to reach nums[n - 1]
. The test cases are generated such that you can reach nums[n - 1]
.
+Return the minimum number of jumps to reach index n - 1
. The test cases are generated such that you can reach index n - 1
.
Example 1:
diff --git a/solution/0000-0099/0049.Group Anagrams/README.md b/solution/0000-0099/0049.Group Anagrams/README.md
index 404f965482ca4..20255463c7d4d 100644
--- a/solution/0000-0099/0049.Group Anagrams/README.md
+++ b/solution/0000-0099/0049.Group Anagrams/README.md
@@ -19,30 +19,41 @@ tags:
-给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
-
-字母异位词 是由重新排列源单词的所有字母得到的一个新单词。
+给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
示例 1:
-
-输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
-输出: [["bat"],["nat","tan"],["ate","eat","tea"]]
+
+
输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
+
+
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]
+
+
解释:
+
+
+ - 在 strs 中没有字符串可以通过重新排列来形成
"bat"
。
+ - 字符串
"nat"
和 "tan"
是字母异位词,因为它们可以重新排列以形成彼此。
+ - 字符串
"ate"
,"eat"
和 "tea"
是字母异位词,因为它们可以重新排列以形成彼此。
+
+
示例 2:
-
-输入: strs = [""]
-输出: [[""]]
-
+
+
输入: strs = [""]
+
+
输出: [[""]]
+
示例 3:
-
-输入: strs = ["a"]
-输出: [["a"]]
+
+
输入: strs = ["a"]
+
+
输出: [["a"]]
+
diff --git a/solution/0000-0099/0066.Plus One/README.md b/solution/0000-0099/0066.Plus One/README.md
index 6c48f063bb6d3..a63a22c802037 100644
--- a/solution/0000-0099/0066.Plus One/README.md
+++ b/solution/0000-0099/0066.Plus One/README.md
@@ -17,11 +17,9 @@ tags:
-给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。
+给定一个表示 大整数 的整数数组 digits
,其中 digits[i]
是整数的第 i
位数字。这些数字按从左到右,从最高位到最低位排列。这个大整数不包含任何前导 0
。
-最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
-
-你可以假设除了整数 0 之外,这个整数不会以零开头。
+将大整数加 1,并返回结果的数字数组。
@@ -31,6 +29,8 @@ tags:
输入:digits = [1,2,3]
输出:[1,2,4]
解释:输入数组表示数字 123。
+加 1 后得到 123 + 1 = 124。
+因此,结果应该是 [1,2,4]。
示例 2:
@@ -39,6 +39,8 @@ tags:
输入:digits = [4,3,2,1]
输出:[4,3,2,2]
解释:输入数组表示数字 4321。
+加 1 后得到 4321 + 1 = 4322。
+因此,结果应该是 [4,3,2,2]。
示例 3:
@@ -58,6 +60,7 @@ tags:
1 <= digits.length <= 100
0 <= digits[i] <= 9
+ digits
不包含任何前导 0
。
diff --git a/solution/0000-0099/0098.Validate Binary Search Tree/README.md b/solution/0000-0099/0098.Validate Binary Search Tree/README.md
index 0f2ca49cb6046..183e61e90c5e7 100644
--- a/solution/0000-0099/0098.Validate Binary Search Tree/README.md
+++ b/solution/0000-0099/0098.Validate Binary Search Tree/README.md
@@ -24,8 +24,8 @@ tags:
有效 二叉搜索树定义如下:
- - 节点的左子树只包含 小于 当前节点的数。
- - 节点的右子树只包含 大于 当前节点的数。
+ - 节点的左子树只包含 严格小于 当前节点的数。
+ - 节点的右子树只包含 严格大于 当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
diff --git a/solution/0000-0099/0098.Validate Binary Search Tree/README_EN.md b/solution/0000-0099/0098.Validate Binary Search Tree/README_EN.md
index ffeedfb757f39..a78f24d74a2a9 100644
--- a/solution/0000-0099/0098.Validate Binary Search Tree/README_EN.md
+++ b/solution/0000-0099/0098.Validate Binary Search Tree/README_EN.md
@@ -24,8 +24,8 @@ tags:
A valid BST is defined as follows:
- - The left subtree of a node contains only nodes with keys less than the node's key.
- - The right subtree of a node contains only nodes with keys greater than the node's key.
+ - The left subtree of a node contains only nodes with keys strictly less than the node's key.
+ - The right subtree of a node contains only nodes with keys strictly greater than the node's key.
- Both the left and right subtrees must also be binary search trees.
diff --git a/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/README.md b/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/README.md
index 8ba0c6018f8ad..84abca6565357 100644
--- a/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/README.md
+++ b/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/README.md
@@ -56,7 +56,15 @@ tags:
-### 方法一
+### 方法一:DFS
+
+我们先将链表转换为数组 $\textit{nums}$,然后使用深度优先搜索构造二叉搜索树。
+
+我们定义一个函数 $\textit{dfs}(i, j)$,其中 $i$ 和 $j$ 表示当前区间为 $[i, j]$。每次我们选择区间中间位置 $\textit{mid}$ 的数字作为根节点,递归地构造左侧区间 $[i, \textit{mid} - 1]$ 的子树,以及右侧区间 $[\textit{mid} + 1, j]$ 的子树。最后返回 $\textit{mid}$ 对应的节点作为当前子树的根节点。
+
+在主函数中,我们只需要调用 $\textit{dfs}(0, n - 1)$ 并返回即可。
+
+时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是链表的长度。
@@ -75,20 +83,19 @@ tags:
# self.left = left
# self.right = right
class Solution:
- def sortedListToBST(self, head: ListNode) -> TreeNode:
- def buildBST(nums, start, end):
- if start > end:
+ def sortedListToBST(self, head: Optional[ListNode]) -> Optional[TreeNode]:
+ def dfs(i: int, j: int) -> Optional[TreeNode]:
+ if i > j:
return None
- mid = (start + end) >> 1
- return TreeNode(
- nums[mid], buildBST(nums, start, mid - 1), buildBST(nums, mid + 1, end)
- )
+ mid = (i + j) >> 1
+ l, r = dfs(i, mid - 1), dfs(mid + 1, j)
+ return TreeNode(nums[mid], l, r)
nums = []
while head:
nums.append(head.val)
head = head.next
- return buildBST(nums, 0, len(nums) - 1)
+ return dfs(0, len(nums) - 1)
```
#### Java
@@ -120,23 +127,23 @@ class Solution:
* }
*/
class Solution {
+ private List nums = new ArrayList<>();
+
public TreeNode sortedListToBST(ListNode head) {
- List nums = new ArrayList<>();
for (; head != null; head = head.next) {
nums.add(head.val);
}
- return buildBST(nums, 0, nums.size() - 1);
+ return dfs(0, nums.size() - 1);
}
- private TreeNode buildBST(List nums, int start, int end) {
- if (start > end) {
+ private TreeNode dfs(int i, int j) {
+ if (i > j) {
return null;
}
- int mid = (start + end) >> 1;
- TreeNode root = new TreeNode(nums.get(mid));
- root.left = buildBST(nums, start, mid - 1);
- root.right = buildBST(nums, mid + 1, end);
- return root;
+ int mid = (i + j) >> 1;
+ TreeNode left = dfs(i, mid - 1);
+ TreeNode right = dfs(mid + 1, j);
+ return new TreeNode(nums.get(mid), left, right);
}
}
```
@@ -169,22 +176,19 @@ class Solution {
public:
TreeNode* sortedListToBST(ListNode* head) {
vector nums;
- for (; head != nullptr; head = head->next) {
+ for (; head; head = head->next) {
nums.push_back(head->val);
}
- return buildBST(nums, 0, nums.size() - 1);
- }
-
-private:
- TreeNode* buildBST(vector& nums, int start, int end) {
- if (start > end) {
- return nullptr;
- }
- int mid = (start + end) / 2;
- TreeNode* root = new TreeNode(nums[mid]);
- root->left = buildBST(nums, start, mid - 1);
- root->right = buildBST(nums, mid + 1, end);
- return root;
+ auto dfs = [&](this auto&& dfs, int i, int j) -> TreeNode* {
+ if (i > j) {
+ return nullptr;
+ }
+ int mid = (i + j) >> 1;
+ TreeNode* left = dfs(i, mid - 1);
+ TreeNode* right = dfs(mid + 1, j);
+ return new TreeNode(nums[mid], left, right);
+ };
+ return dfs(0, nums.size() - 1);
}
};
```
@@ -209,23 +213,20 @@ private:
*/
func sortedListToBST(head *ListNode) *TreeNode {
nums := []int{}
- for head != nil {
+ for ; head != nil; head = head.Next {
nums = append(nums, head.Val)
- head = head.Next
- }
- return buildBST(nums, 0, len(nums)-1)
-}
-
-func buildBST(nums []int, start, end int) *TreeNode {
- if start > end {
- return nil
}
- mid := (start + end) >> 1
- return &TreeNode{
- Val: nums[mid],
- Left: buildBST(nums, start, mid-1),
- Right: buildBST(nums, mid+1, end),
+ var dfs func(i, j int) *TreeNode
+ dfs = func(i, j int) *TreeNode {
+ if i > j {
+ return nil
+ }
+ mid := (i + j) >> 1
+ left := dfs(i, mid-1)
+ right := dfs(mid+1, j)
+ return &TreeNode{nums[mid], left, right}
}
+ return dfs(0, len(nums)-1)
}
```
@@ -258,26 +259,21 @@ func buildBST(nums []int, start, end int) *TreeNode {
* }
*/
-const find = (start: ListNode | null, end: ListNode | null) => {
- let fast = start;
- let slow = start;
- while (fast !== end && fast.next !== end) {
- fast = fast.next.next;
- slow = slow.next;
- }
- return slow;
-};
-
-const build = (start: ListNode | null, end: ListNode | null) => {
- if (start == end) {
- return null;
- }
- const node = find(start, end);
- return new TreeNode(node.val, build(start, node), build(node.next, end));
-};
-
function sortedListToBST(head: ListNode | null): TreeNode | null {
- return build(head, null);
+ const nums: number[] = [];
+ for (; head; head = head.next) {
+ nums.push(head.val);
+ }
+ const dfs = (i: number, j: number): TreeNode | null => {
+ if (i > j) {
+ return null;
+ }
+ const mid = (i + j) >> 1;
+ const left = dfs(i, mid - 1);
+ const right = dfs(mid + 1, j);
+ return new TreeNode(nums[mid], left, right);
+ };
+ return dfs(0, nums.length - 1);
}
```
@@ -320,27 +316,29 @@ function sortedListToBST(head: ListNode | null): TreeNode | null {
// }
use std::cell::RefCell;
use std::rc::Rc;
+
impl Solution {
- fn build(vals: &Vec, start: usize, end: usize) -> Option>> {
- if start == end {
- return None;
+ pub fn sorted_list_to_bst(head: Option>) -> Option>> {
+ let mut nums = Vec::new();
+ let mut current = head;
+ while let Some(node) = current {
+ nums.push(node.val);
+ current = node.next;
}
- let mid = (start + end) >> 1;
- Some(Rc::new(RefCell::new(TreeNode {
- val: vals[mid],
- left: Self::build(vals, start, mid),
- right: Self::build(vals, mid + 1, end),
- })))
- }
- pub fn sorted_list_to_bst(head: Option>) -> Option>> {
- let mut vals = Vec::new();
- let mut cur = &head;
- while let Some(node) = cur {
- vals.push(node.val);
- cur = &node.next;
+ fn dfs(nums: &[i32]) -> Option>> {
+ if nums.is_empty() {
+ return None;
+ }
+ let mid = nums.len() / 2;
+ Some(Rc::new(RefCell::new(TreeNode {
+ val: nums[mid],
+ left: dfs(&nums[..mid]),
+ right: dfs(&nums[mid + 1..]),
+ })))
}
- Self::build(&vals, 0, vals.len())
+
+ dfs(&nums)
}
}
```
@@ -368,22 +366,20 @@ impl Solution {
* @return {TreeNode}
*/
var sortedListToBST = function (head) {
- const buildBST = (nums, start, end) => {
- if (start > end) {
+ const nums = [];
+ for (; head; head = head.next) {
+ nums.push(head.val);
+ }
+ const dfs = (i, j) => {
+ if (i > j) {
return null;
}
- const mid = (start + end) >> 1;
- const root = new TreeNode(nums[mid]);
- root.left = buildBST(nums, start, mid - 1);
- root.right = buildBST(nums, mid + 1, end);
- return root;
+ const mid = (i + j) >> 1;
+ const left = dfs(i, mid - 1);
+ const right = dfs(mid + 1, j);
+ return new TreeNode(nums[mid], left, right);
};
-
- const nums = new Array();
- for (; head != null; head = head.next) {
- nums.push(head.val);
- }
- return buildBST(nums, 0, nums.length - 1);
+ return dfs(0, nums.length - 1);
};
```
@@ -405,30 +401,38 @@ var sortedListToBST = function (head) {
* struct TreeNode *right;
* };
*/
-struct ListNode* find(struct ListNode* start, struct ListNode* end) {
- struct ListNode* fast = start;
- struct ListNode* slow = start;
- while (fast != end && fast->next != end) {
- fast = fast->next->next;
- slow = slow->next;
- }
- return slow;
-}
-
-struct TreeNode* bulid(struct ListNode* start, struct ListNode* end) {
- if (start == end) {
+struct TreeNode* dfs(int* nums, int i, int j) {
+ if (i > j) {
return NULL;
}
- struct ListNode* node = find(start, end);
- struct TreeNode* ans = malloc(sizeof(struct TreeNode));
- ans->val = node->val;
- ans->left = bulid(start, node);
- ans->right = bulid(node->next, end);
- return ans;
+ int mid = (i + j) >> 1;
+ struct TreeNode* left = dfs(nums, i, mid - 1);
+ struct TreeNode* right = dfs(nums, mid + 1, j);
+ struct TreeNode* root = (struct TreeNode*) malloc(sizeof(struct TreeNode));
+ root->val = nums[mid];
+ root->left = left;
+ root->right = right;
+ return root;
}
struct TreeNode* sortedListToBST(struct ListNode* head) {
- return bulid(head, NULL);
+ int size = 0;
+ struct ListNode* temp = head;
+ while (temp) {
+ size++;
+ temp = temp->next;
+ }
+
+ int* nums = (int*) malloc(size * sizeof(int));
+ temp = head;
+ for (int i = 0; i < size; i++) {
+ nums[i] = temp->val;
+ temp = temp->next;
+ }
+
+ struct TreeNode* root = dfs(nums, 0, size - 1);
+ free(nums);
+ return root;
}
```
diff --git a/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/README_EN.md b/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/README_EN.md
index 79f70e47c211b..fff3994332340 100644
--- a/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/README_EN.md
+++ b/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/README_EN.md
@@ -52,7 +52,15 @@ tags:
-### Solution 1
+### Solution 1: DFS
+
+We first convert the linked list to an array $\textit{nums}$, and then use depth-first search to construct the binary search tree.
+
+We define a function $\textit{dfs}(i, j)$, where $i$ and $j$ represent the current interval $[i, j]$. Each time, we choose the number at the middle position $\textit{mid}$ of the interval as the root node, recursively construct the left subtree for the interval $[i, \textit{mid} - 1]$, and the right subtree for the interval $[\textit{mid} + 1, j]$. Finally, we return the node corresponding to $\textit{mid}$ as the root node of the current subtree.
+
+In the main function, we just need to call $\textit{dfs}(0, n - 1)$ and return the result.
+
+The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the linked list.
@@ -71,20 +79,19 @@ tags:
# self.left = left
# self.right = right
class Solution:
- def sortedListToBST(self, head: ListNode) -> TreeNode:
- def buildBST(nums, start, end):
- if start > end:
+ def sortedListToBST(self, head: Optional[ListNode]) -> Optional[TreeNode]:
+ def dfs(i: int, j: int) -> Optional[TreeNode]:
+ if i > j:
return None
- mid = (start + end) >> 1
- return TreeNode(
- nums[mid], buildBST(nums, start, mid - 1), buildBST(nums, mid + 1, end)
- )
+ mid = (i + j) >> 1
+ l, r = dfs(i, mid - 1), dfs(mid + 1, j)
+ return TreeNode(nums[mid], l, r)
nums = []
while head:
nums.append(head.val)
head = head.next
- return buildBST(nums, 0, len(nums) - 1)
+ return dfs(0, len(nums) - 1)
```
#### Java
@@ -116,23 +123,23 @@ class Solution:
* }
*/
class Solution {
+ private List nums = new ArrayList<>();
+
public TreeNode sortedListToBST(ListNode head) {
- List nums = new ArrayList<>();
for (; head != null; head = head.next) {
nums.add(head.val);
}
- return buildBST(nums, 0, nums.size() - 1);
+ return dfs(0, nums.size() - 1);
}
- private TreeNode buildBST(List nums, int start, int end) {
- if (start > end) {
+ private TreeNode dfs(int i, int j) {
+ if (i > j) {
return null;
}
- int mid = (start + end) >> 1;
- TreeNode root = new TreeNode(nums.get(mid));
- root.left = buildBST(nums, start, mid - 1);
- root.right = buildBST(nums, mid + 1, end);
- return root;
+ int mid = (i + j) >> 1;
+ TreeNode left = dfs(i, mid - 1);
+ TreeNode right = dfs(mid + 1, j);
+ return new TreeNode(nums.get(mid), left, right);
}
}
```
@@ -165,22 +172,19 @@ class Solution {
public:
TreeNode* sortedListToBST(ListNode* head) {
vector nums;
- for (; head != nullptr; head = head->next) {
+ for (; head; head = head->next) {
nums.push_back(head->val);
}
- return buildBST(nums, 0, nums.size() - 1);
- }
-
-private:
- TreeNode* buildBST(vector& nums, int start, int end) {
- if (start > end) {
- return nullptr;
- }
- int mid = (start + end) / 2;
- TreeNode* root = new TreeNode(nums[mid]);
- root->left = buildBST(nums, start, mid - 1);
- root->right = buildBST(nums, mid + 1, end);
- return root;
+ auto dfs = [&](this auto&& dfs, int i, int j) -> TreeNode* {
+ if (i > j) {
+ return nullptr;
+ }
+ int mid = (i + j) >> 1;
+ TreeNode* left = dfs(i, mid - 1);
+ TreeNode* right = dfs(mid + 1, j);
+ return new TreeNode(nums[mid], left, right);
+ };
+ return dfs(0, nums.size() - 1);
}
};
```
@@ -205,23 +209,20 @@ private:
*/
func sortedListToBST(head *ListNode) *TreeNode {
nums := []int{}
- for head != nil {
+ for ; head != nil; head = head.Next {
nums = append(nums, head.Val)
- head = head.Next
- }
- return buildBST(nums, 0, len(nums)-1)
-}
-
-func buildBST(nums []int, start, end int) *TreeNode {
- if start > end {
- return nil
}
- mid := (start + end) >> 1
- return &TreeNode{
- Val: nums[mid],
- Left: buildBST(nums, start, mid-1),
- Right: buildBST(nums, mid+1, end),
+ var dfs func(i, j int) *TreeNode
+ dfs = func(i, j int) *TreeNode {
+ if i > j {
+ return nil
+ }
+ mid := (i + j) >> 1
+ left := dfs(i, mid-1)
+ right := dfs(mid+1, j)
+ return &TreeNode{nums[mid], left, right}
}
+ return dfs(0, len(nums)-1)
}
```
@@ -254,26 +255,21 @@ func buildBST(nums []int, start, end int) *TreeNode {
* }
*/
-const find = (start: ListNode | null, end: ListNode | null) => {
- let fast = start;
- let slow = start;
- while (fast !== end && fast.next !== end) {
- fast = fast.next.next;
- slow = slow.next;
- }
- return slow;
-};
-
-const build = (start: ListNode | null, end: ListNode | null) => {
- if (start == end) {
- return null;
- }
- const node = find(start, end);
- return new TreeNode(node.val, build(start, node), build(node.next, end));
-};
-
function sortedListToBST(head: ListNode | null): TreeNode | null {
- return build(head, null);
+ const nums: number[] = [];
+ for (; head; head = head.next) {
+ nums.push(head.val);
+ }
+ const dfs = (i: number, j: number): TreeNode | null => {
+ if (i > j) {
+ return null;
+ }
+ const mid = (i + j) >> 1;
+ const left = dfs(i, mid - 1);
+ const right = dfs(mid + 1, j);
+ return new TreeNode(nums[mid], left, right);
+ };
+ return dfs(0, nums.length - 1);
}
```
@@ -316,27 +312,29 @@ function sortedListToBST(head: ListNode | null): TreeNode | null {
// }
use std::cell::RefCell;
use std::rc::Rc;
+
impl Solution {
- fn build(vals: &Vec, start: usize, end: usize) -> Option>> {
- if start == end {
- return None;
+ pub fn sorted_list_to_bst(head: Option>) -> Option>> {
+ let mut nums = Vec::new();
+ let mut current = head;
+ while let Some(node) = current {
+ nums.push(node.val);
+ current = node.next;
}
- let mid = (start + end) >> 1;
- Some(Rc::new(RefCell::new(TreeNode {
- val: vals[mid],
- left: Self::build(vals, start, mid),
- right: Self::build(vals, mid + 1, end),
- })))
- }
- pub fn sorted_list_to_bst(head: Option>) -> Option>> {
- let mut vals = Vec::new();
- let mut cur = &head;
- while let Some(node) = cur {
- vals.push(node.val);
- cur = &node.next;
+ fn dfs(nums: &[i32]) -> Option>> {
+ if nums.is_empty() {
+ return None;
+ }
+ let mid = nums.len() / 2;
+ Some(Rc::new(RefCell::new(TreeNode {
+ val: nums[mid],
+ left: dfs(&nums[..mid]),
+ right: dfs(&nums[mid + 1..]),
+ })))
}
- Self::build(&vals, 0, vals.len())
+
+ dfs(&nums)
}
}
```
@@ -364,22 +362,20 @@ impl Solution {
* @return {TreeNode}
*/
var sortedListToBST = function (head) {
- const buildBST = (nums, start, end) => {
- if (start > end) {
+ const nums = [];
+ for (; head; head = head.next) {
+ nums.push(head.val);
+ }
+ const dfs = (i, j) => {
+ if (i > j) {
return null;
}
- const mid = (start + end) >> 1;
- const root = new TreeNode(nums[mid]);
- root.left = buildBST(nums, start, mid - 1);
- root.right = buildBST(nums, mid + 1, end);
- return root;
+ const mid = (i + j) >> 1;
+ const left = dfs(i, mid - 1);
+ const right = dfs(mid + 1, j);
+ return new TreeNode(nums[mid], left, right);
};
-
- const nums = new Array();
- for (; head != null; head = head.next) {
- nums.push(head.val);
- }
- return buildBST(nums, 0, nums.length - 1);
+ return dfs(0, nums.length - 1);
};
```
@@ -401,30 +397,38 @@ var sortedListToBST = function (head) {
* struct TreeNode *right;
* };
*/
-struct ListNode* find(struct ListNode* start, struct ListNode* end) {
- struct ListNode* fast = start;
- struct ListNode* slow = start;
- while (fast != end && fast->next != end) {
- fast = fast->next->next;
- slow = slow->next;
- }
- return slow;
-}
-
-struct TreeNode* bulid(struct ListNode* start, struct ListNode* end) {
- if (start == end) {
+struct TreeNode* dfs(int* nums, int i, int j) {
+ if (i > j) {
return NULL;
}
- struct ListNode* node = find(start, end);
- struct TreeNode* ans = malloc(sizeof(struct TreeNode));
- ans->val = node->val;
- ans->left = bulid(start, node);
- ans->right = bulid(node->next, end);
- return ans;
+ int mid = (i + j) >> 1;
+ struct TreeNode* left = dfs(nums, i, mid - 1);
+ struct TreeNode* right = dfs(nums, mid + 1, j);
+ struct TreeNode* root = (struct TreeNode*) malloc(sizeof(struct TreeNode));
+ root->val = nums[mid];
+ root->left = left;
+ root->right = right;
+ return root;
}
struct TreeNode* sortedListToBST(struct ListNode* head) {
- return bulid(head, NULL);
+ int size = 0;
+ struct ListNode* temp = head;
+ while (temp) {
+ size++;
+ temp = temp->next;
+ }
+
+ int* nums = (int*) malloc(size * sizeof(int));
+ temp = head;
+ for (int i = 0; i < size; i++) {
+ nums[i] = temp->val;
+ temp = temp->next;
+ }
+
+ struct TreeNode* root = dfs(nums, 0, size - 1);
+ free(nums);
+ return root;
}
```
diff --git a/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/Solution.c b/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/Solution.c
index f32e42d04329e..bfeda09b4b167 100644
--- a/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/Solution.c
+++ b/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/Solution.c
@@ -13,28 +13,36 @@
* struct TreeNode *right;
* };
*/
-struct ListNode* find(struct ListNode* start, struct ListNode* end) {
- struct ListNode* fast = start;
- struct ListNode* slow = start;
- while (fast != end && fast->next != end) {
- fast = fast->next->next;
- slow = slow->next;
- }
- return slow;
-}
-
-struct TreeNode* bulid(struct ListNode* start, struct ListNode* end) {
- if (start == end) {
+struct TreeNode* dfs(int* nums, int i, int j) {
+ if (i > j) {
return NULL;
}
- struct ListNode* node = find(start, end);
- struct TreeNode* ans = malloc(sizeof(struct TreeNode));
- ans->val = node->val;
- ans->left = bulid(start, node);
- ans->right = bulid(node->next, end);
- return ans;
+ int mid = (i + j) >> 1;
+ struct TreeNode* left = dfs(nums, i, mid - 1);
+ struct TreeNode* right = dfs(nums, mid + 1, j);
+ struct TreeNode* root = (struct TreeNode*) malloc(sizeof(struct TreeNode));
+ root->val = nums[mid];
+ root->left = left;
+ root->right = right;
+ return root;
}
struct TreeNode* sortedListToBST(struct ListNode* head) {
- return bulid(head, NULL);
-}
\ No newline at end of file
+ int size = 0;
+ struct ListNode* temp = head;
+ while (temp) {
+ size++;
+ temp = temp->next;
+ }
+
+ int* nums = (int*) malloc(size * sizeof(int));
+ temp = head;
+ for (int i = 0; i < size; i++) {
+ nums[i] = temp->val;
+ temp = temp->next;
+ }
+
+ struct TreeNode* root = dfs(nums, 0, size - 1);
+ free(nums);
+ return root;
+}
diff --git a/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/Solution.cpp b/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/Solution.cpp
index ee5cfcc48ece5..1eb0fe703542a 100644
--- a/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/Solution.cpp
+++ b/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/Solution.cpp
@@ -23,21 +23,18 @@ class Solution {
public:
TreeNode* sortedListToBST(ListNode* head) {
vector nums;
- for (; head != nullptr; head = head->next) {
+ for (; head; head = head->next) {
nums.push_back(head->val);
}
- return buildBST(nums, 0, nums.size() - 1);
+ auto dfs = [&](this auto&& dfs, int i, int j) -> TreeNode* {
+ if (i > j) {
+ return nullptr;
+ }
+ int mid = (i + j) >> 1;
+ TreeNode* left = dfs(i, mid - 1);
+ TreeNode* right = dfs(mid + 1, j);
+ return new TreeNode(nums[mid], left, right);
+ };
+ return dfs(0, nums.size() - 1);
}
-
-private:
- TreeNode* buildBST(vector& nums, int start, int end) {
- if (start > end) {
- return nullptr;
- }
- int mid = (start + end) / 2;
- TreeNode* root = new TreeNode(nums[mid]);
- root->left = buildBST(nums, start, mid - 1);
- root->right = buildBST(nums, mid + 1, end);
- return root;
- }
-};
\ No newline at end of file
+};
diff --git a/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/Solution.go b/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/Solution.go
index b66788fc49a2f..6552a289a76a1 100644
--- a/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/Solution.go
+++ b/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/Solution.go
@@ -15,21 +15,18 @@
*/
func sortedListToBST(head *ListNode) *TreeNode {
nums := []int{}
- for head != nil {
+ for ; head != nil; head = head.Next {
nums = append(nums, head.Val)
- head = head.Next
}
- return buildBST(nums, 0, len(nums)-1)
-}
-
-func buildBST(nums []int, start, end int) *TreeNode {
- if start > end {
- return nil
- }
- mid := (start + end) >> 1
- return &TreeNode{
- Val: nums[mid],
- Left: buildBST(nums, start, mid-1),
- Right: buildBST(nums, mid+1, end),
+ var dfs func(i, j int) *TreeNode
+ dfs = func(i, j int) *TreeNode {
+ if i > j {
+ return nil
+ }
+ mid := (i + j) >> 1
+ left := dfs(i, mid-1)
+ right := dfs(mid+1, j)
+ return &TreeNode{nums[mid], left, right}
}
-}
\ No newline at end of file
+ return dfs(0, len(nums)-1)
+}
diff --git a/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/Solution.java b/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/Solution.java
index 1f721b782aeaf..8f48b4cc51a15 100644
--- a/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/Solution.java
+++ b/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/Solution.java
@@ -24,22 +24,22 @@
* }
*/
class Solution {
+ private List nums = new ArrayList<>();
+
public TreeNode sortedListToBST(ListNode head) {
- List nums = new ArrayList<>();
for (; head != null; head = head.next) {
nums.add(head.val);
}
- return buildBST(nums, 0, nums.size() - 1);
+ return dfs(0, nums.size() - 1);
}
- private TreeNode buildBST(List nums, int start, int end) {
- if (start > end) {
+ private TreeNode dfs(int i, int j) {
+ if (i > j) {
return null;
}
- int mid = (start + end) >> 1;
- TreeNode root = new TreeNode(nums.get(mid));
- root.left = buildBST(nums, start, mid - 1);
- root.right = buildBST(nums, mid + 1, end);
- return root;
+ int mid = (i + j) >> 1;
+ TreeNode left = dfs(i, mid - 1);
+ TreeNode right = dfs(mid + 1, j);
+ return new TreeNode(nums.get(mid), left, right);
}
-}
\ No newline at end of file
+}
diff --git a/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/Solution.js b/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/Solution.js
index f8306a421e369..dc5f86343f7db 100644
--- a/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/Solution.js
+++ b/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/Solution.js
@@ -18,20 +18,18 @@
* @return {TreeNode}
*/
var sortedListToBST = function (head) {
- const buildBST = (nums, start, end) => {
- if (start > end) {
+ const nums = [];
+ for (; head; head = head.next) {
+ nums.push(head.val);
+ }
+ const dfs = (i, j) => {
+ if (i > j) {
return null;
}
- const mid = (start + end) >> 1;
- const root = new TreeNode(nums[mid]);
- root.left = buildBST(nums, start, mid - 1);
- root.right = buildBST(nums, mid + 1, end);
- return root;
+ const mid = (i + j) >> 1;
+ const left = dfs(i, mid - 1);
+ const right = dfs(mid + 1, j);
+ return new TreeNode(nums[mid], left, right);
};
-
- const nums = new Array();
- for (; head != null; head = head.next) {
- nums.push(head.val);
- }
- return buildBST(nums, 0, nums.length - 1);
+ return dfs(0, nums.length - 1);
};
diff --git a/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/Solution.py b/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/Solution.py
index 3afda8b8cc901..a1dc40741c84c 100644
--- a/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/Solution.py
+++ b/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/Solution.py
@@ -10,17 +10,16 @@
# self.left = left
# self.right = right
class Solution:
- def sortedListToBST(self, head: ListNode) -> TreeNode:
- def buildBST(nums, start, end):
- if start > end:
+ def sortedListToBST(self, head: Optional[ListNode]) -> Optional[TreeNode]:
+ def dfs(i: int, j: int) -> Optional[TreeNode]:
+ if i > j:
return None
- mid = (start + end) >> 1
- return TreeNode(
- nums[mid], buildBST(nums, start, mid - 1), buildBST(nums, mid + 1, end)
- )
+ mid = (i + j) >> 1
+ l, r = dfs(i, mid - 1), dfs(mid + 1, j)
+ return TreeNode(nums[mid], l, r)
nums = []
while head:
nums.append(head.val)
head = head.next
- return buildBST(nums, 0, len(nums) - 1)
+ return dfs(0, len(nums) - 1)
diff --git a/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/Solution.rs b/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/Solution.rs
index 2d96335ac0ffb..acb7860a69bf0 100644
--- a/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/Solution.rs
+++ b/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/Solution.rs
@@ -34,26 +34,28 @@
// }
use std::cell::RefCell;
use std::rc::Rc;
+
impl Solution {
- fn build(vals: &Vec, start: usize, end: usize) -> Option>> {
- if start == end {
- return None;
+ pub fn sorted_list_to_bst(head: Option>) -> Option>> {
+ let mut nums = Vec::new();
+ let mut current = head;
+ while let Some(node) = current {
+ nums.push(node.val);
+ current = node.next;
}
- let mid = (start + end) >> 1;
- Some(Rc::new(RefCell::new(TreeNode {
- val: vals[mid],
- left: Self::build(vals, start, mid),
- right: Self::build(vals, mid + 1, end),
- })))
- }
- pub fn sorted_list_to_bst(head: Option>) -> Option>> {
- let mut vals = Vec::new();
- let mut cur = &head;
- while let Some(node) = cur {
- vals.push(node.val);
- cur = &node.next;
+ fn dfs(nums: &[i32]) -> Option>> {
+ if nums.is_empty() {
+ return None;
+ }
+ let mid = nums.len() / 2;
+ Some(Rc::new(RefCell::new(TreeNode {
+ val: nums[mid],
+ left: dfs(&nums[..mid]),
+ right: dfs(&nums[mid + 1..]),
+ })))
}
- Self::build(&vals, 0, vals.len())
+
+ dfs(&nums)
}
}
diff --git a/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/Solution.ts b/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/Solution.ts
index 8f9a88f34b619..3c4e72f7c6099 100644
--- a/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/Solution.ts
+++ b/solution/0100-0199/0109.Convert Sorted List to Binary Search Tree/Solution.ts
@@ -24,24 +24,19 @@
* }
*/
-const find = (start: ListNode | null, end: ListNode | null) => {
- let fast = start;
- let slow = start;
- while (fast !== end && fast.next !== end) {
- fast = fast.next.next;
- slow = slow.next;
- }
- return slow;
-};
-
-const build = (start: ListNode | null, end: ListNode | null) => {
- if (start == end) {
- return null;
- }
- const node = find(start, end);
- return new TreeNode(node.val, build(start, node), build(node.next, end));
-};
-
function sortedListToBST(head: ListNode | null): TreeNode | null {
- return build(head, null);
+ const nums: number[] = [];
+ for (; head; head = head.next) {
+ nums.push(head.val);
+ }
+ const dfs = (i: number, j: number): TreeNode | null => {
+ if (i > j) {
+ return null;
+ }
+ const mid = (i + j) >> 1;
+ const left = dfs(i, mid - 1);
+ const right = dfs(mid + 1, j);
+ return new TreeNode(nums[mid], left, right);
+ };
+ return dfs(0, nums.length - 1);
}
diff --git a/solution/0100-0199/0115.Distinct Subsequences/README.md b/solution/0100-0199/0115.Distinct Subsequences/README.md
index b83f98dc83184..37dc3ad6e5e52 100644
--- a/solution/0100-0199/0115.Distinct Subsequences/README.md
+++ b/solution/0100-0199/0115.Distinct Subsequences/README.md
@@ -17,7 +17,9 @@ tags:
-给你两个字符串 s
和 t
,统计并返回在 s
的 子序列 中 t
出现的个数,结果需要对 109 + 7 取模。
+给你两个字符串 s
和 t
,统计并返回在 s
的 子序列 中 t
出现的个数。
+
+测试用例保证结果在 32 位有符号整数范围内。
diff --git a/solution/0100-0199/0118.Pascal's Triangle/README.md b/solution/0100-0199/0118.Pascal's Triangle/README.md
index fd03f8d453b2d..d15d69697e1bf 100644
--- a/solution/0100-0199/0118.Pascal's Triangle/README.md
+++ b/solution/0100-0199/0118.Pascal's Triangle/README.md
@@ -57,7 +57,7 @@ tags:
我们先创建一个答案数组 $f$,然后将 $f$ 的第一行元素设为 $[1]$。接下来,我们从第二行开始,每一行的开头和结尾元素都是 $1$,其它 $f[i][j] = f[i - 1][j - 1] + f[i - 1][j]$。
-时间复杂度 $O(n^2)$,空间复杂度 $O(n^2)$。其中 $n$ 是行数。
+时间复杂度 $O(n^2)$,其中 $n$ 为给定的行数。忽略答案的空间消耗,空间复杂度 $O(1)$。
@@ -83,8 +83,8 @@ class Solution {
for (int i = 0; i < numRows - 1; ++i) {
List g = new ArrayList<>();
g.add(1);
- for (int j = 0; j < f.get(i).size() - 1; ++j) {
- g.add(f.get(i).get(j) + f.get(i).get(j + 1));
+ for (int j = 1; j < f.get(i).size(); ++j) {
+ g.add(f.get(i).get(j - 1) + f.get(i).get(j));
}
g.add(1);
f.add(g);
@@ -105,8 +105,8 @@ public:
for (int i = 0; i < numRows - 1; ++i) {
vector g;
g.push_back(1);
- for (int j = 0; j < f[i].size() - 1; ++j) {
- g.push_back(f[i][j] + f[i][j + 1]);
+ for (int j = 1; j < f[i].size(); ++j) {
+ g.push_back(f[i][j - 1] + f[i][j]);
}
g.push_back(1);
f.push_back(g);
@@ -123,8 +123,8 @@ func generate(numRows int) [][]int {
f := [][]int{[]int{1}}
for i := 0; i < numRows-1; i++ {
g := []int{1}
- for j := 0; j < len(f[i])-1; j++ {
- g = append(g, f[i][j]+f[i][j+1])
+ for j := 1; j < len(f[i]); j++ {
+ g = append(g, f[i][j-1]+f[i][j])
}
g = append(g, 1)
f = append(f, g)
@@ -140,8 +140,8 @@ function generate(numRows: number): number[][] {
const f: number[][] = [[1]];
for (let i = 0; i < numRows - 1; ++i) {
const g: number[] = [1];
- for (let j = 0; j < f[i].length - 1; ++j) {
- g.push(f[i][j] + f[i][j + 1]);
+ for (let j = 1; j < f[i].length; ++j) {
+ g.push(f[i][j - 1] + f[i][j]);
}
g.push(1);
f.push(g);
@@ -154,21 +154,17 @@ function generate(numRows: number): number[][] {
```rust
impl Solution {
- #[allow(dead_code)]
pub fn generate(num_rows: i32) -> Vec> {
- let mut ret_vec: Vec> = Vec::new();
- let mut cur_vec: Vec = Vec::new();
-
- for i in 0..num_rows as usize {
- let mut new_vec: Vec = vec![1; i + 1];
- for j in 1..i {
- new_vec[j] = cur_vec[j - 1] + cur_vec[j];
+ let mut f = vec![vec![1]];
+ for i in 1..num_rows {
+ let mut g = vec![1];
+ for j in 1..f[i as usize - 1].len() {
+ g.push(f[i as usize - 1][j - 1] + f[i as usize - 1][j]);
}
- cur_vec = new_vec.clone();
- ret_vec.push(new_vec);
+ g.push(1);
+ f.push(g);
}
-
- ret_vec
+ f
}
}
```
@@ -184,8 +180,8 @@ var generate = function (numRows) {
const f = [[1]];
for (let i = 0; i < numRows - 1; ++i) {
const g = [1];
- for (let j = 0; j < f[i].length - 1; ++j) {
- g.push(f[i][j] + f[i][j + 1]);
+ for (let j = 1; j < f[i].length; ++j) {
+ g.push(f[i][j - 1] + f[i][j]);
}
g.push(1);
f.push(g);
@@ -194,6 +190,25 @@ var generate = function (numRows) {
};
```
+#### C#
+
+```cs
+public class Solution {
+ public IList> Generate(int numRows) {
+ var f = new List> { new List { 1 } };
+ for (int i = 1; i < numRows; ++i) {
+ var g = new List { 1 };
+ for (int j = 1; j < f[i - 1].Count; ++j) {
+ g.Add(f[i - 1][j - 1] + f[i - 1][j]);
+ }
+ g.Add(1);
+ f.Add(g);
+ }
+ return f;
+ }
+}
+```
+
diff --git a/solution/0100-0199/0118.Pascal's Triangle/README_EN.md b/solution/0100-0199/0118.Pascal's Triangle/README_EN.md
index f98f9bb00258a..6f0ebd1725081 100644
--- a/solution/0100-0199/0118.Pascal's Triangle/README_EN.md
+++ b/solution/0100-0199/0118.Pascal's Triangle/README_EN.md
@@ -44,9 +44,9 @@ tags:
### Solution 1: Simulation
-First, we create an answer array $f$, and then set the first row of $f$ to $[1]$. Next, starting from the second row, the first and last elements of each row are $1$, and the other elements are calculated by $f[i][j] = f[i - 1][j - 1] + f[i - 1][j]$.
+We first create an answer array $f$, then set the first row of $f$ to $[1]$. Next, starting from the second row, the first and last elements of each row are $1$, and for other elements $f[i][j] = f[i - 1][j - 1] + f[i - 1][j]$.
-The time complexity is $O(n^2)$, and the space complexity is $O(n^2)$. Here, $n$ is the number of rows.
+The time complexity is $O(n^2)$, where $n$ is the given number of rows. Ignoring the space consumption of the answer, the space complexity is $O(1)$.
@@ -72,8 +72,8 @@ class Solution {
for (int i = 0; i < numRows - 1; ++i) {
List g = new ArrayList<>();
g.add(1);
- for (int j = 0; j < f.get(i).size() - 1; ++j) {
- g.add(f.get(i).get(j) + f.get(i).get(j + 1));
+ for (int j = 1; j < f.get(i).size(); ++j) {
+ g.add(f.get(i).get(j - 1) + f.get(i).get(j));
}
g.add(1);
f.add(g);
@@ -94,8 +94,8 @@ public:
for (int i = 0; i < numRows - 1; ++i) {
vector g;
g.push_back(1);
- for (int j = 0; j < f[i].size() - 1; ++j) {
- g.push_back(f[i][j] + f[i][j + 1]);
+ for (int j = 1; j < f[i].size(); ++j) {
+ g.push_back(f[i][j - 1] + f[i][j]);
}
g.push_back(1);
f.push_back(g);
@@ -112,8 +112,8 @@ func generate(numRows int) [][]int {
f := [][]int{[]int{1}}
for i := 0; i < numRows-1; i++ {
g := []int{1}
- for j := 0; j < len(f[i])-1; j++ {
- g = append(g, f[i][j]+f[i][j+1])
+ for j := 1; j < len(f[i]); j++ {
+ g = append(g, f[i][j-1]+f[i][j])
}
g = append(g, 1)
f = append(f, g)
@@ -129,8 +129,8 @@ function generate(numRows: number): number[][] {
const f: number[][] = [[1]];
for (let i = 0; i < numRows - 1; ++i) {
const g: number[] = [1];
- for (let j = 0; j < f[i].length - 1; ++j) {
- g.push(f[i][j] + f[i][j + 1]);
+ for (let j = 1; j < f[i].length; ++j) {
+ g.push(f[i][j - 1] + f[i][j]);
}
g.push(1);
f.push(g);
@@ -143,21 +143,17 @@ function generate(numRows: number): number[][] {
```rust
impl Solution {
- #[allow(dead_code)]
pub fn generate(num_rows: i32) -> Vec> {
- let mut ret_vec: Vec> = Vec::new();
- let mut cur_vec: Vec = Vec::new();
-
- for i in 0..num_rows as usize {
- let mut new_vec: Vec = vec![1; i + 1];
- for j in 1..i {
- new_vec[j] = cur_vec[j - 1] + cur_vec[j];
+ let mut f = vec![vec![1]];
+ for i in 1..num_rows {
+ let mut g = vec![1];
+ for j in 1..f[i as usize - 1].len() {
+ g.push(f[i as usize - 1][j - 1] + f[i as usize - 1][j]);
}
- cur_vec = new_vec.clone();
- ret_vec.push(new_vec);
+ g.push(1);
+ f.push(g);
}
-
- ret_vec
+ f
}
}
```
@@ -173,8 +169,8 @@ var generate = function (numRows) {
const f = [[1]];
for (let i = 0; i < numRows - 1; ++i) {
const g = [1];
- for (let j = 0; j < f[i].length - 1; ++j) {
- g.push(f[i][j] + f[i][j + 1]);
+ for (let j = 1; j < f[i].length; ++j) {
+ g.push(f[i][j - 1] + f[i][j]);
}
g.push(1);
f.push(g);
@@ -183,6 +179,25 @@ var generate = function (numRows) {
};
```
+#### C#
+
+```cs
+public class Solution {
+ public IList> Generate(int numRows) {
+ var f = new List> { new List { 1 } };
+ for (int i = 1; i < numRows; ++i) {
+ var g = new List { 1 };
+ for (int j = 1; j < f[i - 1].Count; ++j) {
+ g.Add(f[i - 1][j - 1] + f[i - 1][j]);
+ }
+ g.Add(1);
+ f.Add(g);
+ }
+ return f;
+ }
+}
+```
+
diff --git a/solution/0100-0199/0118.Pascal's Triangle/Solution.cpp b/solution/0100-0199/0118.Pascal's Triangle/Solution.cpp
index 62f2014da6b74..d67f423dcce71 100644
--- a/solution/0100-0199/0118.Pascal's Triangle/Solution.cpp
+++ b/solution/0100-0199/0118.Pascal's Triangle/Solution.cpp
@@ -6,8 +6,8 @@ class Solution {
for (int i = 0; i < numRows - 1; ++i) {
vector g;
g.push_back(1);
- for (int j = 0; j < f[i].size() - 1; ++j) {
- g.push_back(f[i][j] + f[i][j + 1]);
+ for (int j = 1; j < f[i].size(); ++j) {
+ g.push_back(f[i][j - 1] + f[i][j]);
}
g.push_back(1);
f.push_back(g);
diff --git a/solution/0100-0199/0118.Pascal's Triangle/Solution.cs b/solution/0100-0199/0118.Pascal's Triangle/Solution.cs
new file mode 100644
index 0000000000000..51f9c369512a8
--- /dev/null
+++ b/solution/0100-0199/0118.Pascal's Triangle/Solution.cs
@@ -0,0 +1,14 @@
+public class Solution {
+ public IList> Generate(int numRows) {
+ var f = new List> { new List { 1 } };
+ for (int i = 1; i < numRows; ++i) {
+ var g = new List { 1 };
+ for (int j = 1; j < f[i - 1].Count; ++j) {
+ g.Add(f[i - 1][j - 1] + f[i - 1][j]);
+ }
+ g.Add(1);
+ f.Add(g);
+ }
+ return f;
+ }
+}
diff --git a/solution/0100-0199/0118.Pascal's Triangle/Solution.go b/solution/0100-0199/0118.Pascal's Triangle/Solution.go
index a754b007af70f..6505391e78e34 100644
--- a/solution/0100-0199/0118.Pascal's Triangle/Solution.go
+++ b/solution/0100-0199/0118.Pascal's Triangle/Solution.go
@@ -2,8 +2,8 @@ func generate(numRows int) [][]int {
f := [][]int{[]int{1}}
for i := 0; i < numRows-1; i++ {
g := []int{1}
- for j := 0; j < len(f[i])-1; j++ {
- g = append(g, f[i][j]+f[i][j+1])
+ for j := 1; j < len(f[i]); j++ {
+ g = append(g, f[i][j-1]+f[i][j])
}
g = append(g, 1)
f = append(f, g)
diff --git a/solution/0100-0199/0118.Pascal's Triangle/Solution.java b/solution/0100-0199/0118.Pascal's Triangle/Solution.java
index 550edb73b4d18..6af3d6d7e377b 100644
--- a/solution/0100-0199/0118.Pascal's Triangle/Solution.java
+++ b/solution/0100-0199/0118.Pascal's Triangle/Solution.java
@@ -5,8 +5,8 @@ public List> generate(int numRows) {
for (int i = 0; i < numRows - 1; ++i) {
List g = new ArrayList<>();
g.add(1);
- for (int j = 0; j < f.get(i).size() - 1; ++j) {
- g.add(f.get(i).get(j) + f.get(i).get(j + 1));
+ for (int j = 1; j < f.get(i).size(); ++j) {
+ g.add(f.get(i).get(j - 1) + f.get(i).get(j));
}
g.add(1);
f.add(g);
diff --git a/solution/0100-0199/0118.Pascal's Triangle/Solution.js b/solution/0100-0199/0118.Pascal's Triangle/Solution.js
index a00aea7a5b57a..0308e343d8bea 100644
--- a/solution/0100-0199/0118.Pascal's Triangle/Solution.js
+++ b/solution/0100-0199/0118.Pascal's Triangle/Solution.js
@@ -6,8 +6,8 @@ var generate = function (numRows) {
const f = [[1]];
for (let i = 0; i < numRows - 1; ++i) {
const g = [1];
- for (let j = 0; j < f[i].length - 1; ++j) {
- g.push(f[i][j] + f[i][j + 1]);
+ for (let j = 1; j < f[i].length; ++j) {
+ g.push(f[i][j - 1] + f[i][j]);
}
g.push(1);
f.push(g);
diff --git a/solution/0100-0199/0118.Pascal's Triangle/Solution.rs b/solution/0100-0199/0118.Pascal's Triangle/Solution.rs
index 695167530c1f3..829e3d11e44b5 100644
--- a/solution/0100-0199/0118.Pascal's Triangle/Solution.rs
+++ b/solution/0100-0199/0118.Pascal's Triangle/Solution.rs
@@ -1,18 +1,14 @@
impl Solution {
- #[allow(dead_code)]
pub fn generate(num_rows: i32) -> Vec> {
- let mut ret_vec: Vec> = Vec::new();
- let mut cur_vec: Vec = Vec::new();
-
- for i in 0..num_rows as usize {
- let mut new_vec: Vec = vec![1; i + 1];
- for j in 1..i {
- new_vec[j] = cur_vec[j - 1] + cur_vec[j];
+ let mut f = vec![vec![1]];
+ for i in 1..num_rows {
+ let mut g = vec![1];
+ for j in 1..f[i as usize - 1].len() {
+ g.push(f[i as usize - 1][j - 1] + f[i as usize - 1][j]);
}
- cur_vec = new_vec.clone();
- ret_vec.push(new_vec);
+ g.push(1);
+ f.push(g);
}
-
- ret_vec
+ f
}
}
diff --git a/solution/0100-0199/0118.Pascal's Triangle/Solution.ts b/solution/0100-0199/0118.Pascal's Triangle/Solution.ts
index 91203940b7925..09857ec026b01 100644
--- a/solution/0100-0199/0118.Pascal's Triangle/Solution.ts
+++ b/solution/0100-0199/0118.Pascal's Triangle/Solution.ts
@@ -2,8 +2,8 @@ function generate(numRows: number): number[][] {
const f: number[][] = [[1]];
for (let i = 0; i < numRows - 1; ++i) {
const g: number[] = [1];
- for (let j = 0; j < f[i].length - 1; ++j) {
- g.push(f[i][j] + f[i][j + 1]);
+ for (let j = 1; j < f[i].length; ++j) {
+ g.push(f[i][j - 1] + f[i][j]);
}
g.push(1);
f.push(g);
diff --git a/solution/0100-0199/0128.Longest Consecutive Sequence/README.md b/solution/0100-0199/0128.Longest Consecutive Sequence/README.md
index a70eb4d730473..3d213b559ee7f 100644
--- a/solution/0100-0199/0128.Longest Consecutive Sequence/README.md
+++ b/solution/0100-0199/0128.Longest Consecutive Sequence/README.md
@@ -38,6 +38,13 @@ tags:
输出:9
+示例 3:
+
+
+输入:nums = [1,0,1,2]
+输出:3
+
+
提示:
diff --git a/solution/0100-0199/0128.Longest Consecutive Sequence/README_EN.md b/solution/0100-0199/0128.Longest Consecutive Sequence/README_EN.md
index e9cf2fe50f0aa..cfd2db7f9dccf 100644
--- a/solution/0100-0199/0128.Longest Consecutive Sequence/README_EN.md
+++ b/solution/0100-0199/0128.Longest Consecutive Sequence/README_EN.md
@@ -38,6 +38,13 @@ tags:
Output: 9
+Example 3:
+
+
+Input: nums = [1,0,1,2]
+Output: 3
+
+
Constraints:
diff --git a/solution/0100-0199/0131.Palindrome Partitioning/README.md b/solution/0100-0199/0131.Palindrome Partitioning/README.md
index b6d99b9b16013..41accb0359e9d 100644
--- a/solution/0100-0199/0131.Palindrome Partitioning/README.md
+++ b/solution/0100-0199/0131.Palindrome Partitioning/README.md
@@ -18,7 +18,7 @@ tags:
-给你一个字符串 s
,请你将 s
分割成一些子串,使每个子串都是 回文串 。返回 s
所有可能的分割方案。
+给你一个字符串 s
,请你将 s
分割成一些 子串,使每个子串都是 回文串 。返回 s
所有可能的分割方案。
@@ -210,7 +210,7 @@ func partition(s string) (ans [][]string) {
```ts
function partition(s: string): string[][] {
const n = s.length;
- const f: boolean[][] = new Array(n).fill(0).map(() => new Array(n).fill(true));
+ const f: boolean[][] = Array.from({ length: n }, () => Array(n).fill(true));
for (let i = n - 1; i >= 0; --i) {
for (let j = i + 1; j < n; ++j) {
f[i][j] = s[i] === s[j] && f[i + 1][j - 1];
diff --git a/solution/0100-0199/0131.Palindrome Partitioning/README_EN.md b/solution/0100-0199/0131.Palindrome Partitioning/README_EN.md
index 269d65cc5fbfd..2c26614c34f7e 100644
--- a/solution/0100-0199/0131.Palindrome Partitioning/README_EN.md
+++ b/solution/0100-0199/0131.Palindrome Partitioning/README_EN.md
@@ -42,7 +42,17 @@ tags:
-### Solution 1
+### Solution 1: Preprocessing + DFS (Backtracking)
+
+We can use dynamic programming to preprocess whether any substring in the string is a palindrome, i.e., $f[i][j]$ indicates whether the substring $s[i..j]$ is a palindrome.
+
+Next, we design a function $dfs(i)$, which represents starting from the $i$-th character of the string and partitioning it into several palindromic substrings, with the current partition scheme being $t$.
+
+If $i = |s|$, it means the partitioning is complete, and we add $t$ to the answer array and then return.
+
+Otherwise, we can start from $i$ and enumerate the end position $j$ from small to large. If $s[i..j]$ is a palindrome, we add $s[i..j]$ to $t$, then continue to recursively call $dfs(j+1)$. When backtracking, we need to pop $s[i..j]$.
+
+The time complexity is $O(n \times 2^n)$, and the space complexity is $O(n^2)$. Here, $n$ is the length of the string.
@@ -191,7 +201,7 @@ func partition(s string) (ans [][]string) {
```ts
function partition(s: string): string[][] {
const n = s.length;
- const f: boolean[][] = new Array(n).fill(0).map(() => new Array(n).fill(true));
+ const f: boolean[][] = Array.from({ length: n }, () => Array(n).fill(true));
for (let i = n - 1; i >= 0; --i) {
for (let j = i + 1; j < n; ++j) {
f[i][j] = s[i] === s[j] && f[i + 1][j - 1];
diff --git a/solution/0100-0199/0131.Palindrome Partitioning/Solution.ts b/solution/0100-0199/0131.Palindrome Partitioning/Solution.ts
index 44eaefcdade44..1a3b24ab43f7f 100644
--- a/solution/0100-0199/0131.Palindrome Partitioning/Solution.ts
+++ b/solution/0100-0199/0131.Palindrome Partitioning/Solution.ts
@@ -1,6 +1,6 @@
function partition(s: string): string[][] {
const n = s.length;
- const f: boolean[][] = new Array(n).fill(0).map(() => new Array(n).fill(true));
+ const f: boolean[][] = Array.from({ length: n }, () => Array(n).fill(true));
for (let i = n - 1; i >= 0; --i) {
for (let j = i + 1; j < n; ++j) {
f[i][j] = s[i] === s[j] && f[i + 1][j - 1];
diff --git a/solution/0100-0199/0132.Palindrome Partitioning II/README.md b/solution/0100-0199/0132.Palindrome Partitioning II/README.md
index 6c79e69452a67..c99793c25db15 100644
--- a/solution/0100-0199/0132.Palindrome Partitioning II/README.md
+++ b/solution/0100-0199/0132.Palindrome Partitioning II/README.md
@@ -198,17 +198,13 @@ func minCut(s string) int {
```ts
function minCut(s: string): number {
const n = s.length;
- const g: boolean[][] = Array(n)
- .fill(0)
- .map(() => Array(n).fill(true));
+ const g: boolean[][] = Array.from({ length: n }, () => Array(n).fill(true));
for (let i = n - 1; ~i; --i) {
for (let j = i + 1; j < n; ++j) {
g[i][j] = s[i] === s[j] && g[i + 1][j - 1];
}
}
- const f: number[] = Array(n)
- .fill(0)
- .map((_, i) => i);
+ const f: number[] = Array.from({ length: n }, (_, i) => i);
for (let i = 1; i < n; ++i) {
for (let j = 0; j <= i; ++j) {
if (g[j][i]) {
diff --git a/solution/0100-0199/0132.Palindrome Partitioning II/README_EN.md b/solution/0100-0199/0132.Palindrome Partitioning II/README_EN.md
index 59ba4c4109bcb..f8122040fd0f2 100644
--- a/solution/0100-0199/0132.Palindrome Partitioning II/README_EN.md
+++ b/solution/0100-0199/0132.Palindrome Partitioning II/README_EN.md
@@ -58,7 +58,21 @@ tags:
-### Solution 1
+### Solution 1: Dynamic Programming
+
+First, we preprocess the string $s$ to determine whether each substring $s[i..j]$ is a palindrome, and record this in a 2D array $g[i][j]$, where $g[i][j]$ indicates whether the substring $s[i..j]$ is a palindrome.
+
+Next, we define $f[i]$ to represent the minimum number of cuts needed for the substring $s[0..i-1]$. Initially, $f[i] = i$.
+
+Next, we consider how to transition the state for $f[i]$. We can enumerate the previous cut point $j$. If the substring $s[j..i]$ is a palindrome, then $f[i]$ can be transitioned from $f[j]$. If $j = 0$, it means that $s[0..i]$ itself is a palindrome, and no cuts are needed, i.e., $f[i] = 0$. Therefore, the state transition equation is as follows:
+
+$$
+f[i] = \min_{0 \leq j \leq i} \begin{cases} f[j-1] + 1, & \textit{if}\ g[j][i] = \textit{True} \\ 0, & \textit{if}\ g[0][i] = \textit{True} \end{cases}
+$$
+
+The answer is $f[n]$, where $n$ is the length of the string $s$.
+
+The time complexity is $O(n^2)$, and the space complexity is $O(n^2)$. Here, $n$ is the length of the string $s$.
@@ -178,17 +192,13 @@ func minCut(s string) int {
```ts
function minCut(s: string): number {
const n = s.length;
- const g: boolean[][] = Array(n)
- .fill(0)
- .map(() => Array(n).fill(true));
+ const g: boolean[][] = Array.from({ length: n }, () => Array(n).fill(true));
for (let i = n - 1; ~i; --i) {
for (let j = i + 1; j < n; ++j) {
g[i][j] = s[i] === s[j] && g[i + 1][j - 1];
}
}
- const f: number[] = Array(n)
- .fill(0)
- .map((_, i) => i);
+ const f: number[] = Array.from({ length: n }, (_, i) => i);
for (let i = 1; i < n; ++i) {
for (let j = 0; j <= i; ++j) {
if (g[j][i]) {
diff --git a/solution/0100-0199/0132.Palindrome Partitioning II/Solution.ts b/solution/0100-0199/0132.Palindrome Partitioning II/Solution.ts
index 23486486dda2f..877bdaff29afd 100644
--- a/solution/0100-0199/0132.Palindrome Partitioning II/Solution.ts
+++ b/solution/0100-0199/0132.Palindrome Partitioning II/Solution.ts
@@ -1,16 +1,12 @@
function minCut(s: string): number {
const n = s.length;
- const g: boolean[][] = Array(n)
- .fill(0)
- .map(() => Array(n).fill(true));
+ const g: boolean[][] = Array.from({ length: n }, () => Array(n).fill(true));
for (let i = n - 1; ~i; --i) {
for (let j = i + 1; j < n; ++j) {
g[i][j] = s[i] === s[j] && g[i + 1][j - 1];
}
}
- const f: number[] = Array(n)
- .fill(0)
- .map((_, i) => i);
+ const f: number[] = Array.from({ length: n }, (_, i) => i);
for (let i = 1; i < n; ++i) {
for (let j = 0; j <= i; ++j) {
if (g[j][i]) {
diff --git a/solution/0100-0199/0133.Clone Graph/README.md b/solution/0100-0199/0133.Clone Graph/README.md
index 68bcd02dffc94..50e374c99314d 100644
--- a/solution/0100-0199/0133.Clone Graph/README.md
+++ b/solution/0100-0199/0133.Clone Graph/README.md
@@ -92,7 +92,20 @@ class Node {
-### 方法一
+### 方法一:哈希表 + DFS
+
+我们用一个哈希表 $\textit{g}$ 记录原图中的每个节点和它的拷贝节点之间的对应关系,然后进行深度优先搜索。
+
+我们定义函数 $\text{dfs}(node)$,它的功能是返回 $\textit{node}$ 节点的拷贝节点。$\text{dfs}(node)$ 的过程如下:
+
+- 如果 $\textit{node}$ 是 $\text{null}$,那么 $\text{dfs}(node)$ 的返回值是 $\text{null}$。
+- 如果 $\textit{node}$ 在 $\textit{g}$ 中,那么 $\text{dfs}(node)$ 的返回值是 $\textit{g}[node]$。
+- 否则我们创建一个新的节点 $\textit{cloned}$,并将 $\textit{g}[node]$ 的值设为 $\textit{cloned}$,然后遍历 $\textit{node}$ 的所有邻居节点 $\textit{nxt}$,并将 $\textit{cloned}$ 的邻居节点列表中加入 $\text{dfs}(nxt)$。
+- 最后返回 $\textit{cloned}$。
+
+在主函数中,我们返回 $\text{dfs}(node)$。
+
+时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是节点的数量。
@@ -107,23 +120,24 @@ class Node:
self.neighbors = neighbors if neighbors is not None else []
"""
+from typing import Optional
-class Solution:
- def cloneGraph(self, node: 'Node') -> 'Node':
- visited = defaultdict()
- def clone(node):
+class Solution:
+ def cloneGraph(self, node: Optional["Node"]) -> Optional["Node"]:
+ def dfs(node):
if node is None:
return None
- if node in visited:
- return visited[node]
- c = Node(node.val)
- visited[node] = c
- for e in node.neighbors:
- c.neighbors.append(clone(e))
- return c
-
- return clone(node)
+ if node in g:
+ return g[node]
+ cloned = Node(node.val)
+ g[node] = cloned
+ for nxt in node.neighbors:
+ cloned.neighbors.append(dfs(nxt))
+ return cloned
+
+ g = defaultdict()
+ return dfs(node)
```
#### Java
@@ -150,21 +164,25 @@ class Node {
*/
class Solution {
- private Map visited = new HashMap<>();
+ private Map g = new HashMap<>();
public Node cloneGraph(Node node) {
+ return dfs(node);
+ }
+
+ private Node dfs(Node node) {
if (node == null) {
return null;
}
- if (visited.containsKey(node)) {
- return visited.get(node);
- }
- Node clone = new Node(node.val);
- visited.put(node, clone);
- for (Node e : node.neighbors) {
- clone.neighbors.add(cloneGraph(e));
+ Node cloned = g.get(node);
+ if (cloned == null) {
+ cloned = new Node(node.val);
+ g.put(node, cloned);
+ for (Node nxt : node.neighbors) {
+ cloned.neighbors.add(dfs(nxt));
+ }
}
- return clone;
+ return cloned;
}
}
```
@@ -195,16 +213,23 @@ public:
class Solution {
public:
- unordered_map visited;
-
Node* cloneGraph(Node* node) {
- if (!node) return nullptr;
- if (visited.count(node)) return visited[node];
- Node* clone = new Node(node->val);
- visited[node] = clone;
- for (auto& e : node->neighbors)
- clone->neighbors.push_back(cloneGraph(e));
- return clone;
+ unordered_map g;
+ auto dfs = [&](this auto&& dfs, Node* node) -> Node* {
+ if (!node) {
+ return nullptr;
+ }
+ if (g.contains(node)) {
+ return g[node];
+ }
+ Node* cloned = new Node(node->val);
+ g[node] = cloned;
+ for (auto& nxt : node->neighbors) {
+ cloned->neighbors.push_back(dfs(nxt));
+ }
+ return cloned;
+ };
+ return dfs(node);
}
};
```
@@ -221,24 +246,23 @@ public:
*/
func cloneGraph(node *Node) *Node {
- visited := map[*Node]*Node{}
- var clone func(node *Node) *Node
- clone = func(node *Node) *Node {
+ g := map[*Node]*Node{}
+ var dfs func(node *Node) *Node
+ dfs = func(node *Node) *Node {
if node == nil {
return nil
}
- if _, ok := visited[node]; ok {
- return visited[node]
+ if n, ok := g[node]; ok {
+ return n
}
- c := &Node{node.Val, []*Node{}}
- visited[node] = c
- for _, e := range node.Neighbors {
- c.Neighbors = append(c.Neighbors, clone(e))
+ cloned := &Node{node.Val, []*Node{}}
+ g[node] = cloned
+ for _, nxt := range node.Neighbors {
+ cloned.Neighbors = append(cloned.Neighbors, dfs(nxt))
}
- return c
+ return cloned
}
-
- return clone(node)
+ return dfs(node)
}
```
@@ -246,74 +270,118 @@ func cloneGraph(node *Node) *Node {
```ts
/**
- * Definition for Node.
- * class Node {
+ * Definition for _Node.
+ * class _Node {
* val: number
- * neighbors: Node[]
- * constructor(val?: number, neighbors?: Node[]) {
+ * neighbors: _Node[]
+ *
+ * constructor(val?: number, neighbors?: _Node[]) {
* this.val = (val===undefined ? 0 : val)
* this.neighbors = (neighbors===undefined ? [] : neighbors)
* }
* }
+ *
*/
-function cloneGraph(node: Node | null): Node | null {
- if (node == null) return null;
-
- const visited = new Map();
- visited.set(node, new Node(node.val));
- const queue = [node];
- while (queue.length) {
- const cur = queue.shift();
- for (let neighbor of cur.neighbors || []) {
- if (!visited.has(neighbor)) {
- queue.push(neighbor);
- const newNeighbor = new Node(neighbor.val, []);
- visited.set(neighbor, newNeighbor);
- }
- const newNode = visited.get(cur);
- newNode.neighbors.push(visited.get(neighbor));
+function cloneGraph(node: _Node | null): _Node | null {
+ const g: Map<_Node, _Node> = new Map();
+ const dfs = (node: _Node | null): _Node | null => {
+ if (!node) {
+ return null;
}
- }
- return visited.get(node);
+ if (g.has(node)) {
+ return g.get(node);
+ }
+ const cloned = new _Node(node.val);
+ g.set(node, cloned);
+ for (const nxt of node.neighbors) {
+ cloned.neighbors.push(dfs(nxt));
+ }
+ return cloned;
+ };
+ return dfs(node);
}
```
+#### JavaScript
+
+```js
+/**
+ * // Definition for a _Node.
+ * function _Node(val, neighbors) {
+ * this.val = val === undefined ? 0 : val;
+ * this.neighbors = neighbors === undefined ? [] : neighbors;
+ * };
+ */
+
+/**
+ * @param {_Node} node
+ * @return {_Node}
+ */
+var cloneGraph = function (node) {
+ const g = new Map();
+ const dfs = node => {
+ if (!node) {
+ return null;
+ }
+ if (g.has(node)) {
+ return g.get(node);
+ }
+ const cloned = new _Node(node.val);
+ g.set(node, cloned);
+ for (const nxt of node.neighbors) {
+ cloned.neighbors.push(dfs(nxt));
+ }
+ return cloned;
+ };
+ return dfs(node);
+};
+```
+
#### C#
```cs
-using System.Collections.Generic;
+/*
+// Definition for a Node.
+public class Node {
+ public int val;
+ public IList neighbors;
+
+ public Node() {
+ val = 0;
+ neighbors = new List();
+ }
+
+ public Node(int _val) {
+ val = _val;
+ neighbors = new List();
+ }
+
+ public Node(int _val, List _neighbors) {
+ val = _val;
+ neighbors = _neighbors;
+ }
+}
+*/
public class Solution {
public Node CloneGraph(Node node) {
- if (node == null) return null;
- var dict = new Dictionary();
- var queue = new Queue();
- queue.Enqueue(CloneVal(node));
- dict.Add(node.val, queue.Peek());
- while (queue.Count > 0)
- {
- var current = queue.Dequeue();
- var newNeighbors = new List(current.neighbors.Count);
- foreach (var oldNeighbor in current.neighbors)
- {
- Node newNeighbor;
- if (!dict.TryGetValue(oldNeighbor.val, out newNeighbor))
- {
- newNeighbor = CloneVal(oldNeighbor);
- queue.Enqueue(newNeighbor);
- dict.Add(newNeighbor.val, newNeighbor);
- }
- newNeighbors.Add(newNeighbor);
+ var g = new Dictionary();
+ Node Dfs(Node n) {
+ if (n == null) {
+ return null;
+ }
+ if (g.ContainsKey(n)) {
+ return g[n];
}
- current.neighbors = newNeighbors;
+ var cloned = new Node(n.val);
+ g[n] = cloned;
+ foreach (var neighbor in n.neighbors) {
+ cloned.neighbors.Add(Dfs(neighbor));
+ }
+ return cloned;
}
- return dict[node.val];
- }
-
- private Node CloneVal(Node node)
- {
- return new Node(node.val, new List(node.neighbors));
+ return Dfs(node);
}
}
```
diff --git a/solution/0100-0199/0133.Clone Graph/README_EN.md b/solution/0100-0199/0133.Clone Graph/README_EN.md
index f64c6ebb729bf..dcefbefee33ab 100644
--- a/solution/0100-0199/0133.Clone Graph/README_EN.md
+++ b/solution/0100-0199/0133.Clone Graph/README_EN.md
@@ -88,7 +88,20 @@ class Node {
-### Solution 1
+### Solution 1: Hash Table + DFS
+
+We use a hash table $\textit{g}$ to record the correspondence between each node in the original graph and its copy, and then perform depth-first search.
+
+We define the function $\text{dfs}(node)$, which returns the copy of the $\textit{node}$. The process of $\text{dfs}(node)$ is as follows:
+
+- If $\textit{node}$ is $\text{null}$, then the return value of $\text{dfs}(node)$ is $\text{null}$.
+- If $\textit{node}$ is in $\textit{g}$, then the return value of $\text{dfs}(node)$ is $\textit{g}[node]$.
+- Otherwise, we create a new node $\textit{cloned}$ and set the value of $\textit{g}[node]$ to $\textit{cloned}$. Then, we traverse all the neighbor nodes $\textit{nxt}$ of $\textit{node}$ and add $\text{dfs}(nxt)$ to the neighbor list of $\textit{cloned}$.
+- Finally, return $\textit{cloned}$.
+
+In the main function, we return $\text{dfs}(node)$.
+
+The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the number of nodes.
@@ -103,23 +116,24 @@ class Node:
self.neighbors = neighbors if neighbors is not None else []
"""
+from typing import Optional
-class Solution:
- def cloneGraph(self, node: 'Node') -> 'Node':
- visited = defaultdict()
- def clone(node):
+class Solution:
+ def cloneGraph(self, node: Optional["Node"]) -> Optional["Node"]:
+ def dfs(node):
if node is None:
return None
- if node in visited:
- return visited[node]
- c = Node(node.val)
- visited[node] = c
- for e in node.neighbors:
- c.neighbors.append(clone(e))
- return c
-
- return clone(node)
+ if node in g:
+ return g[node]
+ cloned = Node(node.val)
+ g[node] = cloned
+ for nxt in node.neighbors:
+ cloned.neighbors.append(dfs(nxt))
+ return cloned
+
+ g = defaultdict()
+ return dfs(node)
```
#### Java
@@ -146,21 +160,25 @@ class Node {
*/
class Solution {
- private Map visited = new HashMap<>();
+ private Map g = new HashMap<>();
public Node cloneGraph(Node node) {
+ return dfs(node);
+ }
+
+ private Node dfs(Node node) {
if (node == null) {
return null;
}
- if (visited.containsKey(node)) {
- return visited.get(node);
- }
- Node clone = new Node(node.val);
- visited.put(node, clone);
- for (Node e : node.neighbors) {
- clone.neighbors.add(cloneGraph(e));
+ Node cloned = g.get(node);
+ if (cloned == null) {
+ cloned = new Node(node.val);
+ g.put(node, cloned);
+ for (Node nxt : node.neighbors) {
+ cloned.neighbors.add(dfs(nxt));
+ }
}
- return clone;
+ return cloned;
}
}
```
@@ -191,16 +209,23 @@ public:
class Solution {
public:
- unordered_map visited;
-
Node* cloneGraph(Node* node) {
- if (!node) return nullptr;
- if (visited.count(node)) return visited[node];
- Node* clone = new Node(node->val);
- visited[node] = clone;
- for (auto& e : node->neighbors)
- clone->neighbors.push_back(cloneGraph(e));
- return clone;
+ unordered_map g;
+ auto dfs = [&](this auto&& dfs, Node* node) -> Node* {
+ if (!node) {
+ return nullptr;
+ }
+ if (g.contains(node)) {
+ return g[node];
+ }
+ Node* cloned = new Node(node->val);
+ g[node] = cloned;
+ for (auto& nxt : node->neighbors) {
+ cloned->neighbors.push_back(dfs(nxt));
+ }
+ return cloned;
+ };
+ return dfs(node);
}
};
```
@@ -217,24 +242,23 @@ public:
*/
func cloneGraph(node *Node) *Node {
- visited := map[*Node]*Node{}
- var clone func(node *Node) *Node
- clone = func(node *Node) *Node {
+ g := map[*Node]*Node{}
+ var dfs func(node *Node) *Node
+ dfs = func(node *Node) *Node {
if node == nil {
return nil
}
- if _, ok := visited[node]; ok {
- return visited[node]
+ if n, ok := g[node]; ok {
+ return n
}
- c := &Node{node.Val, []*Node{}}
- visited[node] = c
- for _, e := range node.Neighbors {
- c.Neighbors = append(c.Neighbors, clone(e))
+ cloned := &Node{node.Val, []*Node{}}
+ g[node] = cloned
+ for _, nxt := range node.Neighbors {
+ cloned.Neighbors = append(cloned.Neighbors, dfs(nxt))
}
- return c
+ return cloned
}
-
- return clone(node)
+ return dfs(node)
}
```
@@ -242,74 +266,118 @@ func cloneGraph(node *Node) *Node {
```ts
/**
- * Definition for Node.
- * class Node {
+ * Definition for _Node.
+ * class _Node {
* val: number
- * neighbors: Node[]
- * constructor(val?: number, neighbors?: Node[]) {
+ * neighbors: _Node[]
+ *
+ * constructor(val?: number, neighbors?: _Node[]) {
* this.val = (val===undefined ? 0 : val)
* this.neighbors = (neighbors===undefined ? [] : neighbors)
* }
* }
+ *
*/
-function cloneGraph(node: Node | null): Node | null {
- if (node == null) return null;
-
- const visited = new Map();
- visited.set(node, new Node(node.val));
- const queue = [node];
- while (queue.length) {
- const cur = queue.shift();
- for (let neighbor of cur.neighbors || []) {
- if (!visited.has(neighbor)) {
- queue.push(neighbor);
- const newNeighbor = new Node(neighbor.val, []);
- visited.set(neighbor, newNeighbor);
- }
- const newNode = visited.get(cur);
- newNode.neighbors.push(visited.get(neighbor));
+function cloneGraph(node: _Node | null): _Node | null {
+ const g: Map<_Node, _Node> = new Map();
+ const dfs = (node: _Node | null): _Node | null => {
+ if (!node) {
+ return null;
}
- }
- return visited.get(node);
+ if (g.has(node)) {
+ return g.get(node);
+ }
+ const cloned = new _Node(node.val);
+ g.set(node, cloned);
+ for (const nxt of node.neighbors) {
+ cloned.neighbors.push(dfs(nxt));
+ }
+ return cloned;
+ };
+ return dfs(node);
}
```
+#### JavaScript
+
+```js
+/**
+ * // Definition for a _Node.
+ * function _Node(val, neighbors) {
+ * this.val = val === undefined ? 0 : val;
+ * this.neighbors = neighbors === undefined ? [] : neighbors;
+ * };
+ */
+
+/**
+ * @param {_Node} node
+ * @return {_Node}
+ */
+var cloneGraph = function (node) {
+ const g = new Map();
+ const dfs = node => {
+ if (!node) {
+ return null;
+ }
+ if (g.has(node)) {
+ return g.get(node);
+ }
+ const cloned = new _Node(node.val);
+ g.set(node, cloned);
+ for (const nxt of node.neighbors) {
+ cloned.neighbors.push(dfs(nxt));
+ }
+ return cloned;
+ };
+ return dfs(node);
+};
+```
+
#### C#
```cs
-using System.Collections.Generic;
+/*
+// Definition for a Node.
+public class Node {
+ public int val;
+ public IList neighbors;
+
+ public Node() {
+ val = 0;
+ neighbors = new List();
+ }
+
+ public Node(int _val) {
+ val = _val;
+ neighbors = new List();
+ }
+
+ public Node(int _val, List _neighbors) {
+ val = _val;
+ neighbors = _neighbors;
+ }
+}
+*/
public class Solution {
public Node CloneGraph(Node node) {
- if (node == null) return null;
- var dict = new Dictionary();
- var queue = new Queue();
- queue.Enqueue(CloneVal(node));
- dict.Add(node.val, queue.Peek());
- while (queue.Count > 0)
- {
- var current = queue.Dequeue();
- var newNeighbors = new List(current.neighbors.Count);
- foreach (var oldNeighbor in current.neighbors)
- {
- Node newNeighbor;
- if (!dict.TryGetValue(oldNeighbor.val, out newNeighbor))
- {
- newNeighbor = CloneVal(oldNeighbor);
- queue.Enqueue(newNeighbor);
- dict.Add(newNeighbor.val, newNeighbor);
- }
- newNeighbors.Add(newNeighbor);
+ var g = new Dictionary();
+ Node Dfs(Node n) {
+ if (n == null) {
+ return null;
+ }
+ if (g.ContainsKey(n)) {
+ return g[n];
}
- current.neighbors = newNeighbors;
+ var cloned = new Node(n.val);
+ g[n] = cloned;
+ foreach (var neighbor in n.neighbors) {
+ cloned.neighbors.Add(Dfs(neighbor));
+ }
+ return cloned;
}
- return dict[node.val];
- }
-
- private Node CloneVal(Node node)
- {
- return new Node(node.val, new List(node.neighbors));
+ return Dfs(node);
}
}
```
diff --git a/solution/0100-0199/0133.Clone Graph/Solution.cpp b/solution/0100-0199/0133.Clone Graph/Solution.cpp
index cfef4bd034149..85d549f56b1fb 100644
--- a/solution/0100-0199/0133.Clone Graph/Solution.cpp
+++ b/solution/0100-0199/0133.Clone Graph/Solution.cpp
@@ -21,15 +21,22 @@ class Node {
class Solution {
public:
- unordered_map visited;
-
Node* cloneGraph(Node* node) {
- if (!node) return nullptr;
- if (visited.count(node)) return visited[node];
- Node* clone = new Node(node->val);
- visited[node] = clone;
- for (auto& e : node->neighbors)
- clone->neighbors.push_back(cloneGraph(e));
- return clone;
+ unordered_map g;
+ auto dfs = [&](this auto&& dfs, Node* node) -> Node* {
+ if (!node) {
+ return nullptr;
+ }
+ if (g.contains(node)) {
+ return g[node];
+ }
+ Node* cloned = new Node(node->val);
+ g[node] = cloned;
+ for (auto& nxt : node->neighbors) {
+ cloned->neighbors.push_back(dfs(nxt));
+ }
+ return cloned;
+ };
+ return dfs(node);
}
-};
\ No newline at end of file
+};
diff --git a/solution/0100-0199/0133.Clone Graph/Solution.cs b/solution/0100-0199/0133.Clone Graph/Solution.cs
index 9abef5a6044c3..24e5fc0a132f4 100644
--- a/solution/0100-0199/0133.Clone Graph/Solution.cs
+++ b/solution/0100-0199/0133.Clone Graph/Solution.cs
@@ -1,34 +1,43 @@
-using System.Collections.Generic;
+/*
+// Definition for a Node.
+public class Node {
+ public int val;
+ public IList neighbors;
+
+ public Node() {
+ val = 0;
+ neighbors = new List();
+ }
+
+ public Node(int _val) {
+ val = _val;
+ neighbors = new List();
+ }
+
+ public Node(int _val, List _neighbors) {
+ val = _val;
+ neighbors = _neighbors;
+ }
+}
+*/
public class Solution {
public Node CloneGraph(Node node) {
- if (node == null) return null;
- var dict = new Dictionary();
- var queue = new Queue();
- queue.Enqueue(CloneVal(node));
- dict.Add(node.val, queue.Peek());
- while (queue.Count > 0)
- {
- var current = queue.Dequeue();
- var newNeighbors = new List(current.neighbors.Count);
- foreach (var oldNeighbor in current.neighbors)
- {
- Node newNeighbor;
- if (!dict.TryGetValue(oldNeighbor.val, out newNeighbor))
- {
- newNeighbor = CloneVal(oldNeighbor);
- queue.Enqueue(newNeighbor);
- dict.Add(newNeighbor.val, newNeighbor);
- }
- newNeighbors.Add(newNeighbor);
+ var g = new Dictionary();
+ Node Dfs(Node n) {
+ if (n == null) {
+ return null;
+ }
+ if (g.ContainsKey(n)) {
+ return g[n];
+ }
+ var cloned = new Node(n.val);
+ g[n] = cloned;
+ foreach (var neighbor in n.neighbors) {
+ cloned.neighbors.Add(Dfs(neighbor));
}
- current.neighbors = newNeighbors;
+ return cloned;
}
- return dict[node.val];
- }
-
- private Node CloneVal(Node node)
- {
- return new Node(node.val, new List(node.neighbors));
+ return Dfs(node);
}
-}
\ No newline at end of file
+}
diff --git a/solution/0100-0199/0133.Clone Graph/Solution.go b/solution/0100-0199/0133.Clone Graph/Solution.go
index 95bd357624546..410ce5c708f41 100644
--- a/solution/0100-0199/0133.Clone Graph/Solution.go
+++ b/solution/0100-0199/0133.Clone Graph/Solution.go
@@ -7,22 +7,21 @@
*/
func cloneGraph(node *Node) *Node {
- visited := map[*Node]*Node{}
- var clone func(node *Node) *Node
- clone = func(node *Node) *Node {
+ g := map[*Node]*Node{}
+ var dfs func(node *Node) *Node
+ dfs = func(node *Node) *Node {
if node == nil {
return nil
}
- if _, ok := visited[node]; ok {
- return visited[node]
+ if n, ok := g[node]; ok {
+ return n
}
- c := &Node{node.Val, []*Node{}}
- visited[node] = c
- for _, e := range node.Neighbors {
- c.Neighbors = append(c.Neighbors, clone(e))
+ cloned := &Node{node.Val, []*Node{}}
+ g[node] = cloned
+ for _, nxt := range node.Neighbors {
+ cloned.Neighbors = append(cloned.Neighbors, dfs(nxt))
}
- return c
+ return cloned
}
-
- return clone(node)
-}
\ No newline at end of file
+ return dfs(node)
+}
diff --git a/solution/0100-0199/0133.Clone Graph/Solution.java b/solution/0100-0199/0133.Clone Graph/Solution.java
index 8f2ae0bdc3974..b5cae79398665 100644
--- a/solution/0100-0199/0133.Clone Graph/Solution.java
+++ b/solution/0100-0199/0133.Clone Graph/Solution.java
@@ -19,20 +19,24 @@ public Node(int _val, ArrayList _neighbors) {
*/
class Solution {
- private Map visited = new HashMap<>();
+ private Map g = new HashMap<>();
public Node cloneGraph(Node node) {
+ return dfs(node);
+ }
+
+ private Node dfs(Node node) {
if (node == null) {
return null;
}
- if (visited.containsKey(node)) {
- return visited.get(node);
+ Node cloned = g.get(node);
+ if (cloned == null) {
+ cloned = new Node(node.val);
+ g.put(node, cloned);
+ for (Node nxt : node.neighbors) {
+ cloned.neighbors.add(dfs(nxt));
+ }
}
- Node clone = new Node(node.val);
- visited.put(node, clone);
- for (Node e : node.neighbors) {
- clone.neighbors.add(cloneGraph(e));
- }
- return clone;
+ return cloned;
}
-}
\ No newline at end of file
+}
diff --git a/solution/0100-0199/0133.Clone Graph/Solution.js b/solution/0100-0199/0133.Clone Graph/Solution.js
new file mode 100644
index 0000000000000..f0f7d53a072b3
--- /dev/null
+++ b/solution/0100-0199/0133.Clone Graph/Solution.js
@@ -0,0 +1,30 @@
+/**
+ * // Definition for a _Node.
+ * function _Node(val, neighbors) {
+ * this.val = val === undefined ? 0 : val;
+ * this.neighbors = neighbors === undefined ? [] : neighbors;
+ * };
+ */
+
+/**
+ * @param {_Node} node
+ * @return {_Node}
+ */
+var cloneGraph = function (node) {
+ const g = new Map();
+ const dfs = node => {
+ if (!node) {
+ return null;
+ }
+ if (g.has(node)) {
+ return g.get(node);
+ }
+ const cloned = new _Node(node.val);
+ g.set(node, cloned);
+ for (const nxt of node.neighbors) {
+ cloned.neighbors.push(dfs(nxt));
+ }
+ return cloned;
+ };
+ return dfs(node);
+};
diff --git a/solution/0100-0199/0133.Clone Graph/Solution.py b/solution/0100-0199/0133.Clone Graph/Solution.py
index 366f123af1dae..0f2a0a533cd91 100644
--- a/solution/0100-0199/0133.Clone Graph/Solution.py
+++ b/solution/0100-0199/0133.Clone Graph/Solution.py
@@ -6,20 +6,21 @@ def __init__(self, val = 0, neighbors = None):
self.neighbors = neighbors if neighbors is not None else []
"""
+from typing import Optional
-class Solution:
- def cloneGraph(self, node: 'Node') -> 'Node':
- visited = defaultdict()
- def clone(node):
+class Solution:
+ def cloneGraph(self, node: Optional["Node"]) -> Optional["Node"]:
+ def dfs(node):
if node is None:
return None
- if node in visited:
- return visited[node]
- c = Node(node.val)
- visited[node] = c
- for e in node.neighbors:
- c.neighbors.append(clone(e))
- return c
+ if node in g:
+ return g[node]
+ cloned = Node(node.val)
+ g[node] = cloned
+ for nxt in node.neighbors:
+ cloned.neighbors.append(dfs(nxt))
+ return cloned
- return clone(node)
+ g = defaultdict()
+ return dfs(node)
diff --git a/solution/0100-0199/0133.Clone Graph/Solution.ts b/solution/0100-0199/0133.Clone Graph/Solution.ts
index 59cadc616cf1d..782253d04aba2 100644
--- a/solution/0100-0199/0133.Clone Graph/Solution.ts
+++ b/solution/0100-0199/0133.Clone Graph/Solution.ts
@@ -1,32 +1,32 @@
/**
- * Definition for Node.
- * class Node {
+ * Definition for _Node.
+ * class _Node {
* val: number
- * neighbors: Node[]
- * constructor(val?: number, neighbors?: Node[]) {
+ * neighbors: _Node[]
+ *
+ * constructor(val?: number, neighbors?: _Node[]) {
* this.val = (val===undefined ? 0 : val)
* this.neighbors = (neighbors===undefined ? [] : neighbors)
* }
* }
+ *
*/
-function cloneGraph(node: Node | null): Node | null {
- if (node == null) return null;
-
- const visited = new Map();
- visited.set(node, new Node(node.val));
- const queue = [node];
- while (queue.length) {
- const cur = queue.shift();
- for (let neighbor of cur.neighbors || []) {
- if (!visited.has(neighbor)) {
- queue.push(neighbor);
- const newNeighbor = new Node(neighbor.val, []);
- visited.set(neighbor, newNeighbor);
- }
- const newNode = visited.get(cur);
- newNode.neighbors.push(visited.get(neighbor));
+function cloneGraph(node: _Node | null): _Node | null {
+ const g: Map<_Node, _Node> = new Map();
+ const dfs = (node: _Node | null): _Node | null => {
+ if (!node) {
+ return null;
+ }
+ if (g.has(node)) {
+ return g.get(node);
+ }
+ const cloned = new _Node(node.val);
+ g.set(node, cloned);
+ for (const nxt of node.neighbors) {
+ cloned.neighbors.push(dfs(nxt));
}
- }
- return visited.get(node);
+ return cloned;
+ };
+ return dfs(node);
}
diff --git a/solution/0100-0199/0134.Gas Station/README.md b/solution/0100-0199/0134.Gas Station/README.md
index 3ae6856d3f254..b350fca1ed379 100644
--- a/solution/0100-0199/0134.Gas Station/README.md
+++ b/solution/0100-0199/0134.Gas Station/README.md
@@ -57,10 +57,10 @@ tags:
提示:
- gas.length == n
- cost.length == n
+ n == gas.length == cost.length
1 <= n <= 105
0 <= gas[i], cost[i] <= 104
+ - 输入保证答案唯一。
diff --git a/solution/0100-0199/0134.Gas Station/README_EN.md b/solution/0100-0199/0134.Gas Station/README_EN.md
index da715b425416d..2ff776b0c19b4 100644
--- a/solution/0100-0199/0134.Gas Station/README_EN.md
+++ b/solution/0100-0199/0134.Gas Station/README_EN.md
@@ -60,6 +60,7 @@ Therefore, you can't travel around the circuit once no matter where you star
n == gas.length == cost.length
1 <= n <= 105
0 <= gas[i], cost[i] <= 104
+ The input is generated such that the answer is unique.
diff --git a/solution/0100-0199/0135.Candy/README.md b/solution/0100-0199/0135.Candy/README.md
index 4b8fd0ef26673..198e8dc5b90b2 100644
--- a/solution/0100-0199/0135.Candy/README.md
+++ b/solution/0100-0199/0135.Candy/README.md
@@ -23,7 +23,7 @@ tags:
- 每个孩子至少分配到
1
个糖果。
- - 相邻两个孩子评分更高的孩子会获得更多的糖果。
+ - 相邻两个孩子中,评分更高的那个会获得更多的糖果。
请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。
@@ -203,6 +203,35 @@ function candy(ratings: number[]): number {
}
```
+#### Rust
+
+```rust
+impl Solution {
+ pub fn candy(ratings: Vec) -> i32 {
+ let n = ratings.len();
+ let mut left = vec![1; n];
+ let mut right = vec![1; n];
+
+ for i in 1..n {
+ if ratings[i] > ratings[i - 1] {
+ left[i] = left[i - 1] + 1;
+ }
+ }
+
+ for i in (0..n - 1).rev() {
+ if ratings[i] > ratings[i + 1] {
+ right[i] = right[i + 1] + 1;
+ }
+ }
+
+ ratings.iter()
+ .enumerate()
+ .map(|(i, _)| left[i].max(right[i]) as i32)
+ .sum()
+ }
+}
+```
+
#### C#
```cs
@@ -236,46 +265,4 @@ public class Solution {
-
-
-### 方法二
-
-
-
-#### Java
-
-```java
-class Solution {
- public int candy(int[] ratings) {
- int n = ratings.length;
- int up = 0;
- int down = 0;
- int peak = 0;
- int candies = 1;
- for (int i = 1; i < n; i++) {
- if (ratings[i - 1] < ratings[i]) {
- up++;
- peak = up + 1;
- down = 0;
- candies += peak;
- } else if (ratings[i] == ratings[i - 1]) {
- peak = 0;
- up = 0;
- down = 0;
- candies++;
- } else {
- down++;
- up = 0;
- candies += down + (peak > down ? 0 : 1);
- }
- }
- return candies;
- }
-}
-```
-
-
-
-
-
diff --git a/solution/0100-0199/0135.Candy/README_EN.md b/solution/0100-0199/0135.Candy/README_EN.md
index a37b9e3a1bdb1..af62226fa2b1e 100644
--- a/solution/0100-0199/0135.Candy/README_EN.md
+++ b/solution/0100-0199/0135.Candy/README_EN.md
@@ -202,6 +202,35 @@ function candy(ratings: number[]): number {
}
```
+#### Rust
+
+```rust
+impl Solution {
+ pub fn candy(ratings: Vec) -> i32 {
+ let n = ratings.len();
+ let mut left = vec![1; n];
+ let mut right = vec![1; n];
+
+ for i in 1..n {
+ if ratings[i] > ratings[i - 1] {
+ left[i] = left[i - 1] + 1;
+ }
+ }
+
+ for i in (0..n - 1).rev() {
+ if ratings[i] > ratings[i + 1] {
+ right[i] = right[i + 1] + 1;
+ }
+ }
+
+ ratings.iter()
+ .enumerate()
+ .map(|(i, _)| left[i].max(right[i]) as i32)
+ .sum()
+ }
+}
+```
+
#### C#
```cs
@@ -235,46 +264,4 @@ public class Solution {
-
-
-### Solution 2
-
-
-
-#### Java
-
-```java
-class Solution {
- public int candy(int[] ratings) {
- int n = ratings.length;
- int up = 0;
- int down = 0;
- int peak = 0;
- int candies = 1;
- for (int i = 1; i < n; i++) {
- if (ratings[i - 1] < ratings[i]) {
- up++;
- peak = up + 1;
- down = 0;
- candies += peak;
- } else if (ratings[i] == ratings[i - 1]) {
- peak = 0;
- up = 0;
- down = 0;
- candies++;
- } else {
- down++;
- up = 0;
- candies += down + (peak > down ? 0 : 1);
- }
- }
- return candies;
- }
-}
-```
-
-
-
-
-
diff --git a/solution/0100-0199/0135.Candy/Solution.rs b/solution/0100-0199/0135.Candy/Solution.rs
new file mode 100644
index 0000000000000..17ad371df3999
--- /dev/null
+++ b/solution/0100-0199/0135.Candy/Solution.rs
@@ -0,0 +1,25 @@
+impl Solution {
+ pub fn candy(ratings: Vec) -> i32 {
+ let n = ratings.len();
+ let mut left = vec![1; n];
+ let mut right = vec![1; n];
+
+ for i in 1..n {
+ if ratings[i] > ratings[i - 1] {
+ left[i] = left[i - 1] + 1;
+ }
+ }
+
+ for i in (0..n - 1).rev() {
+ if ratings[i] > ratings[i + 1] {
+ right[i] = right[i + 1] + 1;
+ }
+ }
+
+ ratings
+ .iter()
+ .enumerate()
+ .map(|(i, _)| left[i].max(right[i]) as i32)
+ .sum()
+ }
+}
diff --git a/solution/0100-0199/0135.Candy/Solution2.java b/solution/0100-0199/0135.Candy/Solution2.java
deleted file mode 100644
index 12695f93146a2..0000000000000
--- a/solution/0100-0199/0135.Candy/Solution2.java
+++ /dev/null
@@ -1,27 +0,0 @@
-class Solution {
- public int candy(int[] ratings) {
- int n = ratings.length;
- int up = 0;
- int down = 0;
- int peak = 0;
- int candies = 1;
- for (int i = 1; i < n; i++) {
- if (ratings[i - 1] < ratings[i]) {
- up++;
- peak = up + 1;
- down = 0;
- candies += peak;
- } else if (ratings[i] == ratings[i - 1]) {
- peak = 0;
- up = 0;
- down = 0;
- candies++;
- } else {
- down++;
- up = 0;
- candies += down + (peak > down ? 0 : 1);
- }
- }
- return candies;
- }
-}
\ No newline at end of file
diff --git a/solution/0100-0199/0147.Insertion Sort List/README.md b/solution/0100-0199/0147.Insertion Sort List/README.md
index 5f9c2b84a6d09..2ffa1f3e1ff77 100644
--- a/solution/0100-0199/0147.Insertion Sort List/README.md
+++ b/solution/0100-0199/0147.Insertion Sort List/README.md
@@ -181,6 +181,42 @@ var insertionSortList = function (head) {
};
```
+#### Go
+
+```go
+/**
+ * Definition for singly-linked list.
+ * type ListNode struct {
+ * Val int
+ * Next *ListNode
+ * }
+ */
+func insertionSortList(head *ListNode) *ListNode {
+ if head == nil || head.Next == nil {
+ return head
+ }
+ dummy := &ListNode{head.Val, head}
+ pre, cur := dummy, head
+ for cur != nil {
+ if pre.Val <= cur.Val {
+ pre = cur
+ cur = cur.Next
+ continue
+ }
+ p := dummy
+ for p.Next.Val <= cur.Val {
+ p = p.Next
+ }
+ t := cur.Next
+ cur.Next = p.Next
+ p.Next = cur
+ pre.Next = t
+ cur = t
+ }
+ return dummy.Next
+}
+```
+
diff --git a/solution/0100-0199/0147.Insertion Sort List/README_EN.md b/solution/0100-0199/0147.Insertion Sort List/README_EN.md
index 7fc22c79e3e08..6501ceb997a91 100644
--- a/solution/0100-0199/0147.Insertion Sort List/README_EN.md
+++ b/solution/0100-0199/0147.Insertion Sort List/README_EN.md
@@ -171,6 +171,42 @@ var insertionSortList = function (head) {
};
```
+#### Go
+
+```go
+/**
+ * Definition for singly-linked list.
+ * type ListNode struct {
+ * Val int
+ * Next *ListNode
+ * }
+ */
+func insertionSortList(head *ListNode) *ListNode {
+ if head == nil || head.Next == nil {
+ return head
+ }
+ dummy := &ListNode{head.Val, head}
+ pre, cur := dummy, head
+ for cur != nil {
+ if pre.Val <= cur.Val {
+ pre = cur
+ cur = cur.Next
+ continue
+ }
+ p := dummy
+ for p.Next.Val <= cur.Val {
+ p = p.Next
+ }
+ t := cur.Next
+ cur.Next = p.Next
+ p.Next = cur
+ pre.Next = t
+ cur = t
+ }
+ return dummy.Next
+}
+```
+
diff --git a/solution/0100-0199/0147.Insertion Sort List/Solution.go b/solution/0100-0199/0147.Insertion Sort List/Solution.go
new file mode 100644
index 0000000000000..0bb4987697e5e
--- /dev/null
+++ b/solution/0100-0199/0147.Insertion Sort List/Solution.go
@@ -0,0 +1,31 @@
+/**
+ * Definition for singly-linked list.
+ * type ListNode struct {
+ * Val int
+ * Next *ListNode
+ * }
+ */
+func insertionSortList(head *ListNode) *ListNode {
+ if head == nil || head.Next == nil {
+ return head
+ }
+ dummy := &ListNode{head.Val, head}
+ pre, cur := dummy, head
+ for cur != nil {
+ if pre.Val <= cur.Val {
+ pre = cur
+ cur = cur.Next
+ continue
+ }
+ p := dummy
+ for p.Next.Val <= cur.Val {
+ p = p.Next
+ }
+ t := cur.Next
+ cur.Next = p.Next
+ p.Next = cur
+ pre.Next = t
+ cur = t
+ }
+ return dummy.Next
+}
diff --git a/solution/0100-0199/0177.Nth Highest Salary/README.md b/solution/0100-0199/0177.Nth Highest Salary/README.md
index cc3445e0f5168..74da21d30cbf7 100644
--- a/solution/0100-0199/0177.Nth Highest Salary/README.md
+++ b/solution/0100-0199/0177.Nth Highest Salary/README.md
@@ -25,13 +25,13 @@ tags:
| id | int |
| salary | int |
+-------------+------+
-在 SQL 中,id 是该表的主键。
+id 是该表的主键(列中的值互不相同)。
该表的每一行都包含有关员工工资的信息。
-查询 Employee
表中第 n
高的工资。如果没有第 n
个最高工资,查询结果应该为 null
。
+编写一个解决方案查询 Employee
表中第 n
高的 不同 工资。如果少于 n
个不同工资,查询结果应该为 null
。
查询结果格式如下所示。
diff --git a/solution/0100-0199/0177.Nth Highest Salary/README_EN.md b/solution/0100-0199/0177.Nth Highest Salary/README_EN.md
index 37c056f9d75ef..3373a1cd68980 100644
--- a/solution/0100-0199/0177.Nth Highest Salary/README_EN.md
+++ b/solution/0100-0199/0177.Nth Highest Salary/README_EN.md
@@ -31,7 +31,7 @@ Each row of this table contains information about the salary of an employee.
-Write a solution to find the nth
highest salary from the Employee
table. If there is no nth
highest salary, return null
.
+Write a solution to find the nth
highest distinct salary from the Employee
table. If there are less than n
distinct salaries, return null
.
The result format is in the following example.
diff --git a/solution/0100-0199/0184.Department Highest Salary/README.md b/solution/0100-0199/0184.Department Highest Salary/README.md
index f22679744afbb..fe36aca302cbb 100644
--- a/solution/0100-0199/0184.Department Highest Salary/README.md
+++ b/solution/0100-0199/0184.Department Highest Salary/README.md
@@ -114,6 +114,31 @@ WHERE
);
```
+### Pandas
+
+```python
+import pandas as pd
+
+
+def department_highest_salary(
+ employee: pd.DataFrame, department: pd.DataFrame
+) -> pd.DataFrame:
+ # Merge the two tables on departmentId and department id
+ merged = employee.merge(department, left_on='departmentId', right_on='id')
+
+ # Find the maximum salary for each department
+ max_salaries = merged.groupby('departmentId')['salary'].transform('max')
+
+ # Filter employees who have the highest salary in their department
+ top_earners = merged[merged['salary'] == max_salaries]
+
+ # Select required columns and rename them
+ result = top_earners[['name_y', 'name_x', 'salary']].copy()
+ result.columns = ['Department', 'Employee', 'Salary']
+
+ return result
+```
+
diff --git a/solution/0100-0199/0184.Department Highest Salary/README_EN.md b/solution/0100-0199/0184.Department Highest Salary/README_EN.md
index 68aad979846ff..48725a31b1208 100644
--- a/solution/0100-0199/0184.Department Highest Salary/README_EN.md
+++ b/solution/0100-0199/0184.Department Highest Salary/README_EN.md
@@ -116,6 +116,31 @@ WHERE
);
```
+### Pandas
+
+```python
+import pandas as pd
+
+
+def department_highest_salary(
+ employee: pd.DataFrame, department: pd.DataFrame
+) -> pd.DataFrame:
+ # Merge the two tables on departmentId and department id
+ merged = employee.merge(department, left_on='departmentId', right_on='id')
+
+ # Find the maximum salary for each department
+ max_salaries = merged.groupby('departmentId')['salary'].transform('max')
+
+ # Filter employees who have the highest salary in their department
+ top_earners = merged[merged['salary'] == max_salaries]
+
+ # Select required columns and rename them
+ result = top_earners[['name_y', 'name_x', 'salary']].copy()
+ result.columns = ['Department', 'Employee', 'Salary']
+
+ return result
+```
+
diff --git a/solution/0100-0199/0184.Department Highest Salary/Solution.py b/solution/0100-0199/0184.Department Highest Salary/Solution.py
new file mode 100644
index 0000000000000..5b661d76ea904
--- /dev/null
+++ b/solution/0100-0199/0184.Department Highest Salary/Solution.py
@@ -0,0 +1,20 @@
+import pandas as pd
+
+
+def department_highest_salary(
+ employee: pd.DataFrame, department: pd.DataFrame
+) -> pd.DataFrame:
+ # Merge the two tables on departmentId and department id
+ merged = employee.merge(department, left_on='departmentId', right_on='id')
+
+ # Find the maximum salary for each department
+ max_salaries = merged.groupby('departmentId')['salary'].transform('max')
+
+ # Filter employees who have the highest salary in their department
+ top_earners = merged[merged['salary'] == max_salaries]
+
+ # Select required columns and rename them
+ result = top_earners[['name_y', 'name_x', 'salary']].copy()
+ result.columns = ['Department', 'Employee', 'Salary']
+
+ return result
diff --git a/solution/0100-0199/0190.Reverse Bits/README.md b/solution/0100-0199/0190.Reverse Bits/README.md
index e151edf982a68..9bcaffac01ee3 100644
--- a/solution/0100-0199/0190.Reverse Bits/README.md
+++ b/solution/0100-0199/0190.Reverse Bits/README.md
@@ -23,33 +23,72 @@ tags:
- 请注意,在某些语言(如 Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并且不应影响您的实现,因为无论整数是有符号的还是无符号的,其内部的二进制表示形式都是相同的。
- - 在 Java 中,编译器使用二进制补码记法来表示有符号整数。因此,在 示例 2 中,输入表示有符号整数
-3
,输出表示有符号整数 -1073741825
。
+ - 在 Java 中,编译器使用二进制补码记法来表示有符号整数。
-示例 1:
-
-
-输入:n = 00000010100101000001111010011100
-输出:964176192 (00111001011110000010100101000000)
-解释:输入的二进制串 00000010100101000001111010011100 表示无符号整数 43261596,
- 因此返回 964176192,其二进制表示形式为 00111001011110000010100101000000。
-
-示例 2:
-
-
-输入:n = 11111111111111111111111111111101
-输出:3221225471 (10111111111111111111111111111111)
-解释:输入的二进制串 11111111111111111111111111111101 表示无符号整数 4294967293,
- 因此返回 3221225471 其二进制表示形式为 10111111111111111111111111111111 。
+示例 1:
+
+
+
输入:n = 43261596
+
+
输出:964176192
+
+
解释:
+
+
+
+
+ 整数 |
+ 二进制 |
+
+
+ 43261596 |
+ 00000010100101000001111010011100 |
+
+
+ 964176192 |
+ 00111001011110000010100101000000 |
+
+
+
+
+
+示例 2:
+
+
+
输入:n = 2147483644
+
+
输出:1073741822
+
+
解释:
+
+
+
+
+ 整数 |
+ 二进制 |
+
+
+ 2147483644 |
+ 01111111111111111111111111111100 |
+
+
+ 1073741822 |
+ 00111111111111111111111111111110 |
+
+
+
+
提示:
- - 输入是一个长度为
32
的二进制字符串
+ 0 <= n <= 231 - 2
+ n
为偶数
diff --git a/solution/0100-0199/0190.Reverse Bits/README_EN.md b/solution/0100-0199/0190.Reverse Bits/README_EN.md
index c9cb6f63778a4..9463a8ca49e00 100644
--- a/solution/0100-0199/0190.Reverse Bits/README_EN.md
+++ b/solution/0100-0199/0190.Reverse Bits/README_EN.md
@@ -23,31 +23,70 @@ tags:
- Note that in some languages, such as Java, there is no unsigned integer type. In this case, both input and output will be given as a signed integer type. They should not affect your implementation, as the integer's internal binary representation is the same, whether it is signed or unsigned.
- - In Java, the compiler represents the signed integers using 2's complement notation. Therefore, in Example 2 above, the input represents the signed integer
-3
and the output represents the signed integer -1073741825
.
+ - In Java, the compiler represents the signed integers using 2's complement notation.
Example 1:
-
-Input: n = 00000010100101000001111010011100
-Output: 964176192 (00111001011110000010100101000000)
-Explanation: The input binary string 00000010100101000001111010011100 represents the unsigned integer 43261596, so return 964176192 which its binary representation is 00111001011110000010100101000000.
-
+
+
Input: n = 43261596
+
+
Output: 964176192
+
+
Explanation:
+
+
+
+
+ Integer |
+ Binary |
+
+
+ 43261596 |
+ 00000010100101000001111010011100 |
+
+
+ 964176192 |
+ 00111001011110000010100101000000 |
+
+
+
+
Example 2:
-
-Input: n = 11111111111111111111111111111101
-Output: 3221225471 (10111111111111111111111111111111)
-Explanation: The input binary string 11111111111111111111111111111101 represents the unsigned integer 4294967293, so return 3221225471 which its binary representation is 10111111111111111111111111111111.
-
+
+
Input: n = 2147483644
+
+
Output: 1073741822
+
+
Explanation:
+
+
+
+
+ Integer |
+ Binary |
+
+
+ 2147483644 |
+ 01111111111111111111111111111100 |
+
+
+ 1073741822 |
+ 00111111111111111111111111111110 |
+
+
+
+
Constraints:
- - The input must be a binary string of length
32
+ 0 <= n <= 231 - 2
+ n
is even.
diff --git a/solution/0200-0299/0206.Reverse Linked List/README.md b/solution/0200-0299/0206.Reverse Linked List/README.md
index 13c9e67956f8a..3a47400b7a3c0 100644
--- a/solution/0200-0299/0206.Reverse Linked List/README.md
+++ b/solution/0200-0299/0206.Reverse Linked List/README.md
@@ -67,9 +67,9 @@ tags:
### 方法一:头插法
-创建虚拟头节点 $dummy$,遍历链表,将每个节点依次插入 $dummy$ 的下一个节点。遍历结束,返回 $dummy.next$。
+我们创建一个虚拟头节点 $\textit{dummy}$,然后遍历链表,将每个节点依次插入 $\textit{dummy}$ 的下一个节点。遍历结束,返回 $\textit{dummy.next}$。
-时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为链表的长度。
+时间复杂度 $O(n)$,其中 $n$ 为链表的长度。空间复杂度 $O(1)$。
@@ -279,15 +279,15 @@ var reverseList = function (head) {
*/
public class Solution {
public ListNode ReverseList(ListNode head) {
- ListNode pre = null;
- for (ListNode p = head; p != null;)
- {
- ListNode t = p.next;
- p.next = pre;
- pre = p;
- p = t;
+ ListNode dummy = new ListNode();
+ ListNode curr = head;
+ while (curr != null) {
+ ListNode next = curr.next;
+ curr.next = dummy.next;
+ dummy.next = curr;
+ curr = next;
}
- return pre;
+ return dummy.next;
}
}
```
@@ -466,6 +466,33 @@ impl Solution {
}
```
+#### C#
+
+```cs
+/**
+ * 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 ReverseList(ListNode head) {
+ if (head == null || head.next == null) {
+ return head;
+ }
+ ListNode ans = ReverseList(head.next);
+ head.next.next = head;
+ head.next = null;
+ return ans;
+ }
+}
+```
+
diff --git a/solution/0200-0299/0206.Reverse Linked List/README_EN.md b/solution/0200-0299/0206.Reverse Linked List/README_EN.md
index 6ef93b442d5a7..298960c2eaa3b 100644
--- a/solution/0200-0299/0206.Reverse Linked List/README_EN.md
+++ b/solution/0200-0299/0206.Reverse Linked List/README_EN.md
@@ -58,7 +58,11 @@ tags:
-### Solution 1
+### Solution 1: Head Insertion Method
+
+We create a dummy node $\textit{dummy}$, then traverse the linked list and insert each node after the $\textit{dummy}$ node. After traversal, return $\textit{dummy.next}$.
+
+The time complexity is $O(n)$, where $n$ is the length of the linked list. The space complexity is $O(1)$.
@@ -268,15 +272,15 @@ var reverseList = function (head) {
*/
public class Solution {
public ListNode ReverseList(ListNode head) {
- ListNode pre = null;
- for (ListNode p = head; p != null;)
- {
- ListNode t = p.next;
- p.next = pre;
- pre = p;
- p = t;
+ ListNode dummy = new ListNode();
+ ListNode curr = head;
+ while (curr != null) {
+ ListNode next = curr.next;
+ curr.next = dummy.next;
+ dummy.next = curr;
+ curr = next;
}
- return pre;
+ return dummy.next;
}
}
```
@@ -287,7 +291,11 @@ public class Solution {
-### Solution 2
+### Solution 2: Recursion
+
+We recursively reverse all nodes from the second node to the end of the list, then attach the $head$ to the end of the reversed list.
+
+The time complexity is $O(n)$, and the space complexity is $O(n)$. Where $n$ is the length of the linked list.
@@ -451,6 +459,33 @@ impl Solution {
}
```
+#### C#
+
+```cs
+/**
+ * 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 ReverseList(ListNode head) {
+ if (head == null || head.next == null) {
+ return head;
+ }
+ ListNode ans = ReverseList(head.next);
+ head.next.next = head;
+ head.next = null;
+ return ans;
+ }
+}
+```
+
diff --git a/solution/0200-0299/0206.Reverse Linked List/Solution.cs b/solution/0200-0299/0206.Reverse Linked List/Solution.cs
index fd70b47359d14..41cc12eb05aee 100644
--- a/solution/0200-0299/0206.Reverse Linked List/Solution.cs
+++ b/solution/0200-0299/0206.Reverse Linked List/Solution.cs
@@ -11,14 +11,14 @@
*/
public class Solution {
public ListNode ReverseList(ListNode head) {
- ListNode pre = null;
- for (ListNode p = head; p != null;)
- {
- ListNode t = p.next;
- p.next = pre;
- pre = p;
- p = t;
+ ListNode dummy = new ListNode();
+ ListNode curr = head;
+ while (curr != null) {
+ ListNode next = curr.next;
+ curr.next = dummy.next;
+ dummy.next = curr;
+ curr = next;
}
- return pre;
+ return dummy.next;
}
-}
+}
\ No newline at end of file
diff --git a/solution/0200-0299/0206.Reverse Linked List/Solution2.cs b/solution/0200-0299/0206.Reverse Linked List/Solution2.cs
new file mode 100644
index 0000000000000..c3b57890bfd3f
--- /dev/null
+++ b/solution/0200-0299/0206.Reverse Linked List/Solution2.cs
@@ -0,0 +1,22 @@
+/**
+ * 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 ReverseList(ListNode head) {
+ if (head == null || head.next == null) {
+ return head;
+ }
+ ListNode ans = ReverseList(head.next);
+ head.next.next = head;
+ head.next = null;
+ return ans;
+ }
+}
\ No newline at end of file
diff --git a/solution/0200-0299/0228.Summary Ranges/README.md b/solution/0200-0299/0228.Summary Ranges/README.md
index 116f2802681e4..6454d51662d39 100644
--- a/solution/0200-0299/0228.Summary Ranges/README.md
+++ b/solution/0200-0299/0228.Summary Ranges/README.md
@@ -18,7 +18,9 @@ tags:
给定一个 无重复元素 的 有序 整数数组 nums
。
-返回 恰好覆盖数组中所有数字 的 最小有序 区间范围列表 。也就是说,nums
的每个元素都恰好被某个区间范围所覆盖,并且不存在属于某个范围但不属于 nums
的数字 x
。
+区间 [a,b]
是从 a
到 b
(包含)的所有整数的集合。
+
+返回 恰好覆盖数组中所有数字 的 最小有序 区间范围列表 。也就是说,nums
的每个元素都恰好被某个区间范围所覆盖,并且不存在属于某个区间但不属于 nums
的数字 x
。
列表中的每个区间范围 [a,b]
应该按如下格式输出:
diff --git a/solution/0200-0299/0231.Power of Two/README.md b/solution/0200-0299/0231.Power of Two/README.md
index 123794f747746..58c8aebfb77a2 100644
--- a/solution/0200-0299/0231.Power of Two/README.md
+++ b/solution/0200-0299/0231.Power of Two/README.md
@@ -67,7 +67,9 @@ tags:
### 方法一:位运算
-$\texttt{n\&(n-1)}$ 可将最后一个二进制形式的 $n$ 的最后一位 $1$ 移除,若移除后为 $0$,说明 $n$ 是 $2$ 的幂。
+根据位运算的性质,执行 $\texttt{n\&(n-1)}$ 可以消去二进制形式的 $n$ 的最后一位 $1$。因此,如果 $n \gt 0$,并且满足 $\texttt{n\&(n-1)}$ 结果为 $0$,则说明 $n$ 是 $2$ 的幂。
+
+时间复杂度 $O(1)$,空间复杂度 $O(1)$。
@@ -116,6 +118,16 @@ function isPowerOfTwo(n: number): boolean {
}
```
+#### Rust
+
+```rust
+impl Solution {
+ pub fn is_power_of_two(n: i32) -> bool {
+ n > 0 && (n & (n - 1)) == 0
+ }
+}
+```
+
#### JavaScript
```js
@@ -134,11 +146,11 @@ var isPowerOfTwo = function (n) {
-### 方法二:lowbit
+### 方法二:Lowbit
-$\texttt{n\&(-n)}$ 可以得到 $n$ 的最后一位 $1$ 表示的十进制数,若与 $n$ 相等,说明 $n$ 是 $2$ 的幂。
+根据 $\text{lowbit}$ 的定义,我们知道 $\text{lowbit}(x) = x \& (-x)$,可以得到 $n$ 的最后一位 $1$ 表示的十进制数。因此,如果 $n > 0$,并且满足 $\text{lowbit}(n)$ 等于 $n$,则说明 $n$ 是 $2$ 的幂。
-注意:要满足 $n$ 是 $2$ 的幂次方,需要保证 $n$ 大于 $0$。
+时间复杂度 $O(1)$,空间复杂度 $O(1)$。
@@ -183,7 +195,17 @@ func isPowerOfTwo(n int) bool {
```ts
function isPowerOfTwo(n: number): boolean {
- return n > 0 && (n & (n - 1)) === 0;
+ return n > 0 && n === (n & -n);
+}
+```
+
+#### Rust
+
+```rust
+impl Solution {
+ pub fn is_power_of_two(n: i32) -> bool {
+ n > 0 && n == (n & (-n))
+ }
}
```
@@ -195,7 +217,7 @@ function isPowerOfTwo(n: number): boolean {
* @return {boolean}
*/
var isPowerOfTwo = function (n) {
- return n > 0 && n == (n & -n);
+ return n > 0 && n === (n & -n);
};
```
diff --git a/solution/0200-0299/0231.Power of Two/README_EN.md b/solution/0200-0299/0231.Power of Two/README_EN.md
index 53b22983ca354..30345d3519512 100644
--- a/solution/0200-0299/0231.Power of Two/README_EN.md
+++ b/solution/0200-0299/0231.Power of Two/README_EN.md
@@ -62,7 +62,11 @@ tags:
-### Solution 1
+### Solution 1: Bit Manipulation
+
+According to the properties of bit manipulation, executing $\texttt{n\&(n-1)}$ can eliminate the last bit $1$ in the binary form of $n$. Therefore, if $n > 0$ and $\texttt{n\&(n-1)}$ results in $0$, then $n$ is a power of $2$.
+
+The time complexity is $O(1)$, and the space complexity is $O(1)$.
@@ -111,6 +115,16 @@ function isPowerOfTwo(n: number): boolean {
}
```
+#### Rust
+
+```rust
+impl Solution {
+ pub fn is_power_of_two(n: i32) -> bool {
+ n > 0 && (n & (n - 1)) == 0
+ }
+}
+```
+
#### JavaScript
```js
@@ -129,7 +143,11 @@ var isPowerOfTwo = function (n) {
-### Solution 2
+### Solution 2: Lowbit
+
+According to the definition of $\text{lowbit}$, we know that $\text{lowbit}(x) = x \& (-x)$, which can get the decimal number represented by the last bit $1$ of $n$. Therefore, if $n > 0$ and $\text{lowbit}(n)$ equals $n$, then $n$ is a power of $2$.
+
+The time complexity is $O(1)$, and the space complexity is $O(1)$.
@@ -174,7 +192,17 @@ func isPowerOfTwo(n int) bool {
```ts
function isPowerOfTwo(n: number): boolean {
- return n > 0 && (n & (n - 1)) === 0;
+ return n > 0 && n === (n & -n);
+}
+```
+
+#### Rust
+
+```rust
+impl Solution {
+ pub fn is_power_of_two(n: i32) -> bool {
+ n > 0 && n == (n & (-n))
+ }
}
```
@@ -186,7 +214,7 @@ function isPowerOfTwo(n: number): boolean {
* @return {boolean}
*/
var isPowerOfTwo = function (n) {
- return n > 0 && n == (n & -n);
+ return n > 0 && n === (n & -n);
};
```
diff --git a/solution/0200-0299/0231.Power of Two/Solution.rs b/solution/0200-0299/0231.Power of Two/Solution.rs
new file mode 100644
index 0000000000000..d07cc7d8a7e7a
--- /dev/null
+++ b/solution/0200-0299/0231.Power of Two/Solution.rs
@@ -0,0 +1,5 @@
+impl Solution {
+ pub fn is_power_of_two(n: i32) -> bool {
+ n > 0 && (n & (n - 1)) == 0
+ }
+}
diff --git a/solution/0200-0299/0231.Power of Two/Solution2.js b/solution/0200-0299/0231.Power of Two/Solution2.js
index d0b7a66d9343c..1576a49ffb8e6 100644
--- a/solution/0200-0299/0231.Power of Two/Solution2.js
+++ b/solution/0200-0299/0231.Power of Two/Solution2.js
@@ -3,5 +3,5 @@
* @return {boolean}
*/
var isPowerOfTwo = function (n) {
- return n > 0 && n == (n & -n);
+ return n > 0 && n === (n & -n);
};
diff --git a/solution/0200-0299/0231.Power of Two/Solution2.rs b/solution/0200-0299/0231.Power of Two/Solution2.rs
new file mode 100644
index 0000000000000..40010a60b63ba
--- /dev/null
+++ b/solution/0200-0299/0231.Power of Two/Solution2.rs
@@ -0,0 +1,5 @@
+impl Solution {
+ pub fn is_power_of_two(n: i32) -> bool {
+ n > 0 && n == (n & (-n))
+ }
+}
diff --git a/solution/0200-0299/0231.Power of Two/Solution2.ts b/solution/0200-0299/0231.Power of Two/Solution2.ts
index bfb580cec5184..4bdd7d6c71707 100644
--- a/solution/0200-0299/0231.Power of Two/Solution2.ts
+++ b/solution/0200-0299/0231.Power of Two/Solution2.ts
@@ -1,3 +1,3 @@
function isPowerOfTwo(n: number): boolean {
- return n > 0 && (n & (n - 1)) === 0;
+ return n > 0 && n === (n & -n);
}
diff --git a/solution/0200-0299/0234.Palindrome Linked List/README.md b/solution/0200-0299/0234.Palindrome Linked List/README.md
index c6ae9c84a2c3b..3cc316a66d7d1 100644
--- a/solution/0200-0299/0234.Palindrome Linked List/README.md
+++ b/solution/0200-0299/0234.Palindrome Linked List/README.md
@@ -60,7 +60,7 @@ tags:
我们可以先用快慢指针找到链表的中点,接着反转右半部分的链表。然后同时遍历前后两段链表,若前后两段链表节点对应的值不等,说明不是回文链表,否则说明是回文链表。
-时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为链表的长度。
+时间复杂度 $O(n)$,其中 $n$ 为链表的长度。空间复杂度 $O(1)$。
diff --git a/solution/0200-0299/0234.Palindrome Linked List/README_EN.md b/solution/0200-0299/0234.Palindrome Linked List/README_EN.md
index 579cc97d75c93..4eccdad94b92a 100644
--- a/solution/0200-0299/0234.Palindrome Linked List/README_EN.md
+++ b/solution/0200-0299/0234.Palindrome Linked List/README_EN.md
@@ -53,7 +53,11 @@ tags:
-### Solution 1
+### Solution 1: Fast and Slow Pointers
+
+We can use fast and slow pointers to find the middle of the linked list, then reverse the right half of the list. After that, we traverse both halves simultaneously, checking if the corresponding node values are equal. If any pair of values is unequal, it's not a palindrome linked list; otherwise, it is a palindrome linked list.
+
+The time complexity is $O(n)$, where $n$ is the length of the linked list. The space complexity is $O(1)$.
diff --git a/solution/0200-0299/0235.Lowest Common Ancestor of a Binary Search Tree/README.md b/solution/0200-0299/0235.Lowest Common Ancestor of a Binary Search Tree/README.md
index 31998e5c3308e..100331c6a54f1 100644
--- a/solution/0200-0299/0235.Lowest Common Ancestor of a Binary Search Tree/README.md
+++ b/solution/0200-0299/0235.Lowest Common Ancestor of a Binary Search Tree/README.md
@@ -57,15 +57,11 @@ tags:
-### 方法一:迭代或递归
+### 方法一:迭代
-从上到下搜索,找到第一个值位于 $[p.val, q.val]$ 之间的结点即可。
+我们从根节点开始遍历,如果当前节点的值小于 $\textit{p}$ 和 $\textit{q}$ 的值,说明 $\textit{p}$ 和 $\textit{q}$ 应该在当前节点的右子树,因此将当前节点移动到右子节点;如果当前节点的值大于 $\textit{p}$ 和 $\textit{q}$ 的值,说明 $\textit{p}$ 和 $\textit{q}$ 应该在当前节点的左子树,因此将当前节点移动到左子节点;否则说明当前节点就是 $\textit{p}$ 和 $\textit{q}$ 的最近公共祖先,返回当前节点即可。
-既可以用迭代实现,也可以用递归实现。
-
-迭代的时间复杂度为 $O(n)$,空间复杂度为 $O(1)$。
-
-递归的时间复杂度为 $O(n)$,空间复杂度为 $O(n)$。
+时间复杂度 $O(n)$,其中 $n$ 是二叉搜索树的节点个数。空间复杂度 $O(1)$。
@@ -164,9 +160,9 @@ public:
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
for {
- if root.Val < p.Val && root.Val < q.Val {
+ if root.Val < min(p.Val, q.Val) {
root = root.Right
- } else if root.Val > p.Val && root.Val > q.Val {
+ } else if root.Val > max(p.Val, q.Val) {
root = root.Left
} else {
return root
@@ -209,13 +205,47 @@ function lowestCommonAncestor(
}
```
+#### C#
+
+```cs
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public int val;
+ * public TreeNode left;
+ * public TreeNode right;
+ * public TreeNode(int x) { val = x; }
+ * }
+ */
+
+public class Solution {
+ public TreeNode LowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
+ while (true) {
+ if (root.val < Math.Min(p.val, q.val)) {
+ root = root.right;
+ } else if (root.val > Math.Max(p.val, q.val)) {
+ root = root.left;
+ } else {
+ return root;
+ }
+ }
+ }
+}
+```
+
-### 方法二
+### 方法二:递归
+
+我们也可以使用递归的方法来解决这个问题。
+
+我们首先判断当前节点的值是否小于 $\textit{p}$ 和 $\textit{q}$ 的值,如果是,则递归遍历右子树;如果当前节点的值大于 $\textit{p}$ 和 $\textit{q}$ 的值,如果是,则递归遍历左子树;否则说明当前节点就是 $\textit{p}$ 和 $\textit{q}$ 的最近公共祖先,返回当前节点即可。
+
+时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是二叉搜索树的节点个数。
@@ -339,12 +369,42 @@ function lowestCommonAncestor(
p: TreeNode | null,
q: TreeNode | null,
): TreeNode | null {
- if (root.val > p.val && root.val > q.val) return lowestCommonAncestor(root.left, p, q);
- if (root.val < p.val && root.val < q.val) return lowestCommonAncestor(root.right, p, q);
+ if (root.val > p.val && root.val > q.val) {
+ return lowestCommonAncestor(root.left, p, q);
+ }
+ if (root.val < p.val && root.val < q.val) {
+ return lowestCommonAncestor(root.right, p, q);
+ }
return root;
}
```
+#### C#
+
+```cs
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public int val;
+ * public TreeNode left;
+ * public TreeNode right;
+ * public TreeNode(int x) { val = x; }
+ * }
+ */
+
+public class Solution {
+ public TreeNode LowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
+ if (root.val < Math.Min(p.val, q.val)) {
+ return LowestCommonAncestor(root.right, p, q);
+ }
+ if (root.val > Math.Max(p.val, q.val)) {
+ return LowestCommonAncestor(root.left, p, q);
+ }
+ return root;
+ }
+}
+```
+
diff --git a/solution/0200-0299/0235.Lowest Common Ancestor of a Binary Search Tree/README_EN.md b/solution/0200-0299/0235.Lowest Common Ancestor of a Binary Search Tree/README_EN.md
index 9e5d7066ef095..1fe8be223eb17 100644
--- a/solution/0200-0299/0235.Lowest Common Ancestor of a Binary Search Tree/README_EN.md
+++ b/solution/0200-0299/0235.Lowest Common Ancestor of a Binary Search Tree/README_EN.md
@@ -64,7 +64,11 @@ tags:
-### Solution 1
+### Solution 1: Iteration
+
+Starting from the root node, we traverse the tree. If the current node's value is less than both $\textit{p}$ and $\textit{q}$ values, it means that $\textit{p}$ and $\textit{q}$ should be in the right subtree of the current node, so we move to the right child. If the current node's value is greater than both $\textit{p}$ and $\textit{q}$ values, it means that $\textit{p}$ and $\textit{q}$ should be in the left subtree, so we move to the left child. Otherwise, it means the current node is the lowest common ancestor of $\textit{p}$ and $\textit{q}$, so we return the current node.
+
+The time complexity is $O(n)$, where $n$ is the number of nodes in the binary search tree. The space complexity is $O(1)$.
@@ -163,9 +167,9 @@ public:
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
for {
- if root.Val < p.Val && root.Val < q.Val {
+ if root.Val < min(p.Val, q.Val) {
root = root.Right
- } else if root.Val > p.Val && root.Val > q.Val {
+ } else if root.Val > max(p.Val, q.Val) {
root = root.Left
} else {
return root
@@ -208,13 +212,47 @@ function lowestCommonAncestor(
}
```
+#### C#
+
+```cs
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public int val;
+ * public TreeNode left;
+ * public TreeNode right;
+ * public TreeNode(int x) { val = x; }
+ * }
+ */
+
+public class Solution {
+ public TreeNode LowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
+ while (true) {
+ if (root.val < Math.Min(p.val, q.val)) {
+ root = root.right;
+ } else if (root.val > Math.Max(p.val, q.val)) {
+ root = root.left;
+ } else {
+ return root;
+ }
+ }
+ }
+}
+```
+
-### Solution 2
+### Solution 2: Recursion
+
+We can also use a recursive approach to solve this problem.
+
+We first check if the current node's value is less than both $\textit{p}$ and $\textit{q}$ values. If it is, we recursively traverse the right subtree. If the current node's value is greater than both $\textit{p}$ and $\textit{q}$ values, we recursively traverse the left subtree. Otherwise, it means the current node is the lowest common ancestor of $\textit{p}$ and $\textit{q}$, so we return the current node.
+
+The time complexity is $O(n)$, and the space complexity is $O(n)$. Where $n$ is the number of nodes in the binary search tree.
@@ -338,12 +376,42 @@ function lowestCommonAncestor(
p: TreeNode | null,
q: TreeNode | null,
): TreeNode | null {
- if (root.val > p.val && root.val > q.val) return lowestCommonAncestor(root.left, p, q);
- if (root.val < p.val && root.val < q.val) return lowestCommonAncestor(root.right, p, q);
+ if (root.val > p.val && root.val > q.val) {
+ return lowestCommonAncestor(root.left, p, q);
+ }
+ if (root.val < p.val && root.val < q.val) {
+ return lowestCommonAncestor(root.right, p, q);
+ }
return root;
}
```
+#### C#
+
+```cs
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public int val;
+ * public TreeNode left;
+ * public TreeNode right;
+ * public TreeNode(int x) { val = x; }
+ * }
+ */
+
+public class Solution {
+ public TreeNode LowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
+ if (root.val < Math.Min(p.val, q.val)) {
+ return LowestCommonAncestor(root.right, p, q);
+ }
+ if (root.val > Math.Max(p.val, q.val)) {
+ return LowestCommonAncestor(root.left, p, q);
+ }
+ return root;
+ }
+}
+```
+
diff --git a/solution/0200-0299/0235.Lowest Common Ancestor of a Binary Search Tree/Solution.cs b/solution/0200-0299/0235.Lowest Common Ancestor of a Binary Search Tree/Solution.cs
new file mode 100644
index 0000000000000..0c62318d00082
--- /dev/null
+++ b/solution/0200-0299/0235.Lowest Common Ancestor of a Binary Search Tree/Solution.cs
@@ -0,0 +1,23 @@
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public int val;
+ * public TreeNode left;
+ * public TreeNode right;
+ * public TreeNode(int x) { val = x; }
+ * }
+ */
+
+public class Solution {
+ public TreeNode LowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
+ while (true) {
+ if (root.val < Math.Min(p.val, q.val)) {
+ root = root.right;
+ } else if (root.val > Math.Max(p.val, q.val)) {
+ root = root.left;
+ } else {
+ return root;
+ }
+ }
+ }
+}
diff --git a/solution/0200-0299/0235.Lowest Common Ancestor of a Binary Search Tree/Solution.go b/solution/0200-0299/0235.Lowest Common Ancestor of a Binary Search Tree/Solution.go
index 46ac599a9e887..3985db3bf9472 100644
--- a/solution/0200-0299/0235.Lowest Common Ancestor of a Binary Search Tree/Solution.go
+++ b/solution/0200-0299/0235.Lowest Common Ancestor of a Binary Search Tree/Solution.go
@@ -9,12 +9,12 @@
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
for {
- if root.Val < p.Val && root.Val < q.Val {
+ if root.Val < min(p.Val, q.Val) {
root = root.Right
- } else if root.Val > p.Val && root.Val > q.Val {
+ } else if root.Val > max(p.Val, q.Val) {
root = root.Left
} else {
return root
}
}
-}
\ No newline at end of file
+}
diff --git a/solution/0200-0299/0235.Lowest Common Ancestor of a Binary Search Tree/Solution2.cs b/solution/0200-0299/0235.Lowest Common Ancestor of a Binary Search Tree/Solution2.cs
new file mode 100644
index 0000000000000..4b0f3a40385be
--- /dev/null
+++ b/solution/0200-0299/0235.Lowest Common Ancestor of a Binary Search Tree/Solution2.cs
@@ -0,0 +1,21 @@
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public int val;
+ * public TreeNode left;
+ * public TreeNode right;
+ * public TreeNode(int x) { val = x; }
+ * }
+ */
+
+public class Solution {
+ public TreeNode LowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
+ if (root.val < Math.Min(p.val, q.val)) {
+ return LowestCommonAncestor(root.right, p, q);
+ }
+ if (root.val > Math.Max(p.val, q.val)) {
+ return LowestCommonAncestor(root.left, p, q);
+ }
+ return root;
+ }
+}
\ No newline at end of file
diff --git a/solution/0200-0299/0235.Lowest Common Ancestor of a Binary Search Tree/Solution2.ts b/solution/0200-0299/0235.Lowest Common Ancestor of a Binary Search Tree/Solution2.ts
index 767340ae6f213..47fd3383276dd 100644
--- a/solution/0200-0299/0235.Lowest Common Ancestor of a Binary Search Tree/Solution2.ts
+++ b/solution/0200-0299/0235.Lowest Common Ancestor of a Binary Search Tree/Solution2.ts
@@ -17,7 +17,11 @@ function lowestCommonAncestor(
p: TreeNode | null,
q: TreeNode | null,
): TreeNode | null {
- if (root.val > p.val && root.val > q.val) return lowestCommonAncestor(root.left, p, q);
- if (root.val < p.val && root.val < q.val) return lowestCommonAncestor(root.right, p, q);
+ if (root.val > p.val && root.val > q.val) {
+ return lowestCommonAncestor(root.left, p, q);
+ }
+ if (root.val < p.val && root.val < q.val) {
+ return lowestCommonAncestor(root.right, p, q);
+ }
return root;
}
diff --git a/solution/0200-0299/0245.Shortest Word Distance III/README.md b/solution/0200-0299/0245.Shortest Word Distance III/README.md
index 51d9475fc32ee..379385980b016 100644
--- a/solution/0200-0299/0245.Shortest Word Distance III/README.md
+++ b/solution/0200-0299/0245.Shortest Word Distance III/README.md
@@ -56,13 +56,12 @@ tags:
### 方法一:分情况讨论
-先判断 `word1` 和 `word2` 是否相等:
+我们首先判断 $\textit{word1}$ 和 $\textit{word2}$ 是否相等:
-如果相等,遍历数组 `wordsDict`,找到两个 `word1` 的下标 $i$ 和 $j$,求 $i-j$ 的最小值。
+- 如果相等,遍历数组 $\textit{wordsDict}$,找到两个 $\textit{word1}$ 的下标 $i$ 和 $j$,求 $i-j$ 的最小值。
+- 如果不相等,遍历数组 $\textit{wordsDict}$,找到 $\textit{word1}$ 和 $\textit{word2}$ 的下标 $i$ 和 $j$,求 $i-j$ 的最小值。
-如果不相等,遍历数组 `wordsDict`,找到 `word1` 和 `word2` 的下标 $i$ 和 $j$,求 $i-j$ 的最小值。
-
-时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组 `wordsDict` 的长度。
+时间复杂度 $O(n)$,其中 $n$ 为数组 $\textit{wordsDict}$ 的长度。空间复杂度 $O(1)$。
@@ -199,6 +198,40 @@ func abs(x int) int {
}
```
+#### TypeScript
+
+```ts
+function shortestWordDistance(wordsDict: string[], word1: string, word2: string): number {
+ let ans = wordsDict.length;
+ if (word1 === word2) {
+ let j = -1;
+ for (let i = 0; i < wordsDict.length; i++) {
+ if (wordsDict[i] === word1) {
+ if (j !== -1) {
+ ans = Math.min(ans, i - j);
+ }
+ j = i;
+ }
+ }
+ } else {
+ let i = -1,
+ j = -1;
+ for (let k = 0; k < wordsDict.length; k++) {
+ if (wordsDict[k] === word1) {
+ i = k;
+ }
+ if (wordsDict[k] === word2) {
+ j = k;
+ }
+ if (i !== -1 && j !== -1) {
+ ans = Math.min(ans, Math.abs(i - j));
+ }
+ }
+ }
+ return ans;
+}
+```
+
diff --git a/solution/0200-0299/0245.Shortest Word Distance III/README_EN.md b/solution/0200-0299/0245.Shortest Word Distance III/README_EN.md
index 72ab891b39ce6..6fbcb289984fb 100644
--- a/solution/0200-0299/0245.Shortest Word Distance III/README_EN.md
+++ b/solution/0200-0299/0245.Shortest Word Distance III/README_EN.md
@@ -45,7 +45,14 @@ tags:
-### Solution 1
+### Solution 1: Case Analysis
+
+First, we check whether $\textit{word1}$ and $\textit{word2}$ are equal:
+
+- If they are equal, iterate through the array $\textit{wordsDict}$ to find two indices $i$ and $j$ of $\textit{word1}$, and compute the minimum value of $i-j$.
+- If they are not equal, iterate through the array $\textit{wordsDict}$ to find the indices $i$ of $\textit{word1}$ and $j$ of $\textit{word2}$, and compute the minimum value of $i-j$.
+
+The time complexity is $O(n)$, where $n$ is the length of the array $\textit{wordsDict}$. The space complexity is $O(1)$.
@@ -182,6 +189,40 @@ func abs(x int) int {
}
```
+#### TypeScript
+
+```ts
+function shortestWordDistance(wordsDict: string[], word1: string, word2: string): number {
+ let ans = wordsDict.length;
+ if (word1 === word2) {
+ let j = -1;
+ for (let i = 0; i < wordsDict.length; i++) {
+ if (wordsDict[i] === word1) {
+ if (j !== -1) {
+ ans = Math.min(ans, i - j);
+ }
+ j = i;
+ }
+ }
+ } else {
+ let i = -1,
+ j = -1;
+ for (let k = 0; k < wordsDict.length; k++) {
+ if (wordsDict[k] === word1) {
+ i = k;
+ }
+ if (wordsDict[k] === word2) {
+ j = k;
+ }
+ if (i !== -1 && j !== -1) {
+ ans = Math.min(ans, Math.abs(i - j));
+ }
+ }
+ }
+ return ans;
+}
+```
+
diff --git a/solution/0200-0299/0245.Shortest Word Distance III/Solution.ts b/solution/0200-0299/0245.Shortest Word Distance III/Solution.ts
new file mode 100644
index 0000000000000..acb406b3b5ec7
--- /dev/null
+++ b/solution/0200-0299/0245.Shortest Word Distance III/Solution.ts
@@ -0,0 +1,29 @@
+function shortestWordDistance(wordsDict: string[], word1: string, word2: string): number {
+ let ans = wordsDict.length;
+ if (word1 === word2) {
+ let j = -1;
+ for (let i = 0; i < wordsDict.length; i++) {
+ if (wordsDict[i] === word1) {
+ if (j !== -1) {
+ ans = Math.min(ans, i - j);
+ }
+ j = i;
+ }
+ }
+ } else {
+ let i = -1,
+ j = -1;
+ for (let k = 0; k < wordsDict.length; k++) {
+ if (wordsDict[k] === word1) {
+ i = k;
+ }
+ if (wordsDict[k] === word2) {
+ j = k;
+ }
+ if (i !== -1 && j !== -1) {
+ ans = Math.min(ans, Math.abs(i - j));
+ }
+ }
+ }
+ return ans;
+}
diff --git a/solution/0200-0299/0250.Count Univalue Subtrees/README.md b/solution/0200-0299/0250.Count Univalue Subtrees/README.md
index 5bb0e0bde10be..d254ac53f3de5 100644
--- a/solution/0200-0299/0250.Count Univalue Subtrees/README.md
+++ b/solution/0200-0299/0250.Count Univalue Subtrees/README.md
@@ -18,24 +18,42 @@ tags:
-给定一个二叉树,统计该二叉树数值相同的子树个数。
+给定一个二叉树,统计该二叉树数值相同的 子树 个数。
同值子树是指该子树的所有节点都拥有相同的数值。
-示例:
+
+示例 1:
+
-输入: root = [5,1,5,5,5,null,5]
+输入:root = [5,1,5,5,5,null,5]
+输出:4
+
- 5
- / \
- 1 5
- / \ \
- 5 5 5
+示例 2:
-输出: 4
+
+输入:root = []
+输出:0
+示例 3:
+
+
+输入:root = [5,5,5,5,5,null,5]
+输出:6
+
+
+
+
+提示:
+
+
+ - 树中节点的编号在
[0, 1000]
范围内
+ -1000 <= Node.val <= 1000
+
+
## 解法
diff --git a/solution/0200-0299/0252.Meeting Rooms/README.md b/solution/0200-0299/0252.Meeting Rooms/README.md
index db5c3a47d17bf..6b44b73110318 100644
--- a/solution/0200-0299/0252.Meeting Rooms/README.md
+++ b/solution/0200-0299/0252.Meeting Rooms/README.md
@@ -53,9 +53,9 @@ tags:
### 方法一:排序
-我们将会议按照开始时间进行排序,然后遍历排序后的会议,如果当前会议的开始时间小于前一个会议的结束时间,则说明两个会议有重叠,返回 `false` 即可。
+我们将会议按照开始时间进行排序,然后遍历排序后的会议,如果当前会议的开始时间小于前一个会议的结束时间,则说明两个会议有重叠,返回 $\text{false}$,否则继续遍历。
-遍历结束后,返回 `true`。
+如果遍历结束都没有发现重叠的会议,则返回 $\text{true}$。
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(\log n)$。其中 $n$ 为会议数量。
@@ -77,9 +77,7 @@ class Solution {
public boolean canAttendMeetings(int[][] intervals) {
Arrays.sort(intervals, (a, b) -> a[0] - b[0]);
for (int i = 1; i < intervals.length; ++i) {
- var a = intervals[i - 1];
- var b = intervals[i];
- if (a[1] > b[0]) {
+ if (intervals[i - 1][1] > intervals[i][0]) {
return false;
}
}
@@ -94,11 +92,11 @@ class Solution {
class Solution {
public:
bool canAttendMeetings(vector>& intervals) {
- sort(intervals.begin(), intervals.end(), [](const vector& a, const vector& b) {
+ ranges::sort(intervals, [](const auto& a, const auto& b) {
return a[0] < b[0];
});
for (int i = 1; i < intervals.size(); ++i) {
- if (intervals[i][0] < intervals[i - 1][1]) {
+ if (intervals[i - 1][1] > intervals[i][0]) {
return false;
}
}
@@ -141,32 +139,13 @@ function canAttendMeetings(intervals: number[][]): boolean {
```rust
impl Solution {
- #[allow(dead_code)]
- pub fn can_attend_meetings(intervals: Vec>) -> bool {
- if intervals.len() == 1 {
- return true;
- }
-
- let mut intervals = intervals;
-
- // Sort the intervals vector
- intervals.sort_by(|lhs, rhs| lhs[0].cmp(&rhs[0]));
-
- let mut end = -1;
-
- // Begin traverse
- for p in &intervals {
- if end == -1 {
- // This is the first pair
- end = p[1];
- continue;
- }
- if p[0] < end {
+ pub fn can_attend_meetings(mut intervals: Vec>) -> bool {
+ intervals.sort_by(|a, b| a[0].cmp(&b[0]));
+ for i in 1..intervals.len() {
+ if intervals[i - 1][1] > intervals[i][0] {
return false;
}
- end = p[1];
}
-
true
}
}
diff --git a/solution/0200-0299/0252.Meeting Rooms/README_EN.md b/solution/0200-0299/0252.Meeting Rooms/README_EN.md
index e052d217a0a34..3553a9ea56eee 100644
--- a/solution/0200-0299/0252.Meeting Rooms/README_EN.md
+++ b/solution/0200-0299/0252.Meeting Rooms/README_EN.md
@@ -42,7 +42,13 @@ tags:
-### Solution 1
+### Solution 1: Sorting
+
+We sort the meetings based on their start times, and then iterate through the sorted meetings. If the start time of the current meeting is less than the end time of the previous meeting, it indicates that there is an overlap between the two meetings, and we return `false`. Otherwise, we continue iterating.
+
+If no overlap is found by the end of the iteration, we return `true`.
+
+The time complexity is $O(n \times \log n)$, and the space complexity is $O(\log n)$, where $n$ is the number of meetings.
@@ -62,9 +68,7 @@ class Solution {
public boolean canAttendMeetings(int[][] intervals) {
Arrays.sort(intervals, (a, b) -> a[0] - b[0]);
for (int i = 1; i < intervals.length; ++i) {
- var a = intervals[i - 1];
- var b = intervals[i];
- if (a[1] > b[0]) {
+ if (intervals[i - 1][1] > intervals[i][0]) {
return false;
}
}
@@ -79,11 +83,11 @@ class Solution {
class Solution {
public:
bool canAttendMeetings(vector>& intervals) {
- sort(intervals.begin(), intervals.end(), [](const vector& a, const vector& b) {
+ ranges::sort(intervals, [](const auto& a, const auto& b) {
return a[0] < b[0];
});
for (int i = 1; i < intervals.size(); ++i) {
- if (intervals[i][0] < intervals[i - 1][1]) {
+ if (intervals[i - 1][1] > intervals[i][0]) {
return false;
}
}
@@ -126,32 +130,13 @@ function canAttendMeetings(intervals: number[][]): boolean {
```rust
impl Solution {
- #[allow(dead_code)]
- pub fn can_attend_meetings(intervals: Vec>) -> bool {
- if intervals.len() == 1 {
- return true;
- }
-
- let mut intervals = intervals;
-
- // Sort the intervals vector
- intervals.sort_by(|lhs, rhs| lhs[0].cmp(&rhs[0]));
-
- let mut end = -1;
-
- // Begin traverse
- for p in &intervals {
- if end == -1 {
- // This is the first pair
- end = p[1];
- continue;
- }
- if p[0] < end {
+ pub fn can_attend_meetings(mut intervals: Vec>) -> bool {
+ intervals.sort_by(|a, b| a[0].cmp(&b[0]));
+ for i in 1..intervals.len() {
+ if intervals[i - 1][1] > intervals[i][0] {
return false;
}
- end = p[1];
}
-
true
}
}
diff --git a/solution/0200-0299/0252.Meeting Rooms/Solution.cpp b/solution/0200-0299/0252.Meeting Rooms/Solution.cpp
index 7e6b6657fe2e5..9fca6aeed42e3 100644
--- a/solution/0200-0299/0252.Meeting Rooms/Solution.cpp
+++ b/solution/0200-0299/0252.Meeting Rooms/Solution.cpp
@@ -1,14 +1,14 @@
class Solution {
public:
bool canAttendMeetings(vector>& intervals) {
- sort(intervals.begin(), intervals.end(), [](const vector& a, const vector& b) {
+ ranges::sort(intervals, [](const auto& a, const auto& b) {
return a[0] < b[0];
});
for (int i = 1; i < intervals.size(); ++i) {
- if (intervals[i][0] < intervals[i - 1][1]) {
+ if (intervals[i - 1][1] > intervals[i][0]) {
return false;
}
}
return true;
}
-};
\ No newline at end of file
+};
diff --git a/solution/0200-0299/0252.Meeting Rooms/Solution.java b/solution/0200-0299/0252.Meeting Rooms/Solution.java
index 565b05b05f2f8..008f531dfad17 100644
--- a/solution/0200-0299/0252.Meeting Rooms/Solution.java
+++ b/solution/0200-0299/0252.Meeting Rooms/Solution.java
@@ -2,12 +2,10 @@ class Solution {
public boolean canAttendMeetings(int[][] intervals) {
Arrays.sort(intervals, (a, b) -> a[0] - b[0]);
for (int i = 1; i < intervals.length; ++i) {
- var a = intervals[i - 1];
- var b = intervals[i];
- if (a[1] > b[0]) {
+ if (intervals[i - 1][1] > intervals[i][0]) {
return false;
}
}
return true;
}
-}
\ No newline at end of file
+}
diff --git a/solution/0200-0299/0252.Meeting Rooms/Solution.rs b/solution/0200-0299/0252.Meeting Rooms/Solution.rs
index 1ee4bd2d2cc4a..a81f3d2fc39a5 100644
--- a/solution/0200-0299/0252.Meeting Rooms/Solution.rs
+++ b/solution/0200-0299/0252.Meeting Rooms/Solution.rs
@@ -1,30 +1,11 @@
impl Solution {
- #[allow(dead_code)]
- pub fn can_attend_meetings(intervals: Vec>) -> bool {
- if intervals.len() == 1 {
- return true;
- }
-
- let mut intervals = intervals;
-
- // Sort the intervals vector
- intervals.sort_by(|lhs, rhs| lhs[0].cmp(&rhs[0]));
-
- let mut end = -1;
-
- // Begin traverse
- for p in &intervals {
- if end == -1 {
- // This is the first pair
- end = p[1];
- continue;
- }
- if p[0] < end {
+ pub fn can_attend_meetings(mut intervals: Vec>) -> bool {
+ intervals.sort_by(|a, b| a[0].cmp(&b[0]));
+ for i in 1..intervals.len() {
+ if intervals[i - 1][1] > intervals[i][0] {
return false;
}
- end = p[1];
}
-
true
}
}
diff --git a/solution/0200-0299/0253.Meeting Rooms II/README.md b/solution/0200-0299/0253.Meeting Rooms II/README.md
index c330c2024b93d..72e3b0353c53f 100644
--- a/solution/0200-0299/0253.Meeting Rooms II/README.md
+++ b/solution/0200-0299/0253.Meeting Rooms II/README.md
@@ -56,6 +56,169 @@ tags:
### 方法一:差分数组
+我们可以用差分数组来实现。
+
+我们首先找到所有会议的最大结束时间,记为 $m$,然后创建一个长度为 $m + 1$ 的差分数组 $d$,将每个会议的开始时间和结束时间分别加到差分数组的对应位置上,即 $d[l] = d[l] + 1$,而 $d[r] = d[r] - 1$。
+
+然后,我们计算差分数组的前缀和,找出前缀和的最大值,即为所需会议室的最小数量。
+
+时间复杂度 $O(n + m)$,空间复杂度 $O(m)$。其中 $n$ 和 $m$ 分别为会议数量和最大结束时间。
+
+
+
+#### Python3
+
+```python
+class Solution:
+ def minMeetingRooms(self, intervals: List[List[int]]) -> int:
+ m = max(e[1] for e in intervals)
+ d = [0] * (m + 1)
+ for l, r in intervals:
+ d[l] += 1
+ d[r] -= 1
+ ans = s = 0
+ for v in d:
+ s += v
+ ans = max(ans, s)
+ return ans
+```
+
+#### Java
+
+```java
+class Solution {
+ public int minMeetingRooms(int[][] intervals) {
+ int m = 0;
+ for (var e : intervals) {
+ m = Math.max(m, e[1]);
+ }
+ int[] d = new int[m + 1];
+ for (var e : intervals) {
+ ++d[e[0]];
+ --d[e[1]];
+ }
+ int ans = 0, s = 0;
+ for (int v : d) {
+ s += v;
+ ans = Math.max(ans, s);
+ }
+ return ans;
+ }
+}
+```
+
+#### C++
+
+```cpp
+class Solution {
+public:
+ int minMeetingRooms(vector>& intervals) {
+ int m = 0;
+ for (const auto& e : intervals) {
+ m = max(m, e[1]);
+ }
+ vector d(m + 1);
+ for (const auto& e : intervals) {
+ d[e[0]]++;
+ d[e[1]]--;
+ }
+ int ans = 0, s = 0;
+ for (int v : d) {
+ s += v;
+ ans = max(ans, s);
+ }
+ return ans;
+ }
+};
+```
+
+#### Go
+
+```go
+func minMeetingRooms(intervals [][]int) (ans int) {
+ m := 0
+ for _, e := range intervals {
+ m = max(m, e[1])
+ }
+
+ d := make([]int, m+1)
+ for _, e := range intervals {
+ d[e[0]]++
+ d[e[1]]--
+ }
+
+ s := 0
+ for _, v := range d {
+ s += v
+ ans = max(ans, s)
+ }
+ return
+}
+```
+
+#### TypeScript
+
+```ts
+function minMeetingRooms(intervals: number[][]): number {
+ const m = Math.max(...intervals.map(([_, r]) => r));
+ const d: number[] = Array(m + 1).fill(0);
+ for (const [l, r] of intervals) {
+ d[l]++;
+ d[r]--;
+ }
+ let [ans, s] = [0, 0];
+ for (const v of d) {
+ s += v;
+ ans = Math.max(ans, s);
+ }
+ return ans;
+}
+```
+
+#### Rust
+
+```rust
+impl Solution {
+ pub fn min_meeting_rooms(intervals: Vec>) -> i32 {
+ let mut m = 0;
+ for e in &intervals {
+ m = m.max(e[1]);
+ }
+
+ let mut d = vec![0; (m + 1) as usize];
+ for e in intervals {
+ d[e[0] as usize] += 1;
+ d[e[1] as usize] -= 1;
+ }
+
+ let mut ans = 0;
+ let mut s = 0;
+ for v in d {
+ s += v;
+ ans = ans.max(s);
+ }
+
+ ans
+ }
+}
+```
+
+
+
+
+
+
+
+### 方法二:差分(哈希表)
+
+如果题目中的会议时间跨度很大,那么我们可以使用哈希表来代替差分数组。
+
+我们首先创建一个哈希表 $d$,将每个会议的开始时间和结束时间分别加到哈希表的对应位置上,即 $d[l] = d[l] + 1$,而 $d[r] = d[r] - 1$。
+
+然后,我们将哈希表按照键进行排序,计算哈希表的前缀和,找出前缀和的最大值,即为所需会议室的最小数量。
+
+时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为会议数量。
+
#### Python3
@@ -63,11 +226,15 @@ tags:
```python
class Solution:
def minMeetingRooms(self, intervals: List[List[int]]) -> int:
- delta = [0] * 1000010
- for start, end in intervals:
- delta[start] += 1
- delta[end] -= 1
- return max(accumulate(delta))
+ d = defaultdict(int)
+ for l, r in intervals:
+ d[l] += 1
+ d[r] -= 1
+ ans = s = 0
+ for _, v in sorted(d.items()):
+ s += v
+ ans = max(ans, s)
+ return ans
```
#### Java
@@ -75,18 +242,17 @@ class Solution:
```java
class Solution {
public int minMeetingRooms(int[][] intervals) {
- int n = 1000010;
- int[] delta = new int[n];
- for (int[] e : intervals) {
- ++delta[e[0]];
- --delta[e[1]];
+ Map d = new TreeMap<>();
+ for (var e : intervals) {
+ d.merge(e[0], 1, Integer::sum);
+ d.merge(e[1], -1, Integer::sum);
}
- int res = delta[0];
- for (int i = 1; i < n; ++i) {
- delta[i] += delta[i - 1];
- res = Math.max(res, delta[i]);
+ int ans = 0, s = 0;
+ for (var e : d.values()) {
+ s += e;
+ ans = Math.max(ans, s);
}
- return res;
+ return ans;
}
}
```
@@ -97,16 +263,17 @@ class Solution {
class Solution {
public:
int minMeetingRooms(vector>& intervals) {
- int n = 1000010;
- vector delta(n);
- for (auto e : intervals) {
- ++delta[e[0]];
- --delta[e[1]];
+ map d;
+ for (const auto& e : intervals) {
+ d[e[0]]++;
+ d[e[1]]--;
}
- for (int i = 0; i < n - 1; ++i) {
- delta[i + 1] += delta[i];
+ int ans = 0, s = 0;
+ for (auto& [_, v] : d) {
+ s += v;
+ ans = max(ans, s);
}
- return *max_element(delta.begin(), delta.end());
+ return ans;
}
};
```
@@ -114,56 +281,75 @@ public:
#### Go
```go
-func minMeetingRooms(intervals [][]int) int {
- n := 1000010
- delta := make([]int, n)
+func minMeetingRooms(intervals [][]int) (ans int) {
+ d := make(map[int]int)
for _, e := range intervals {
- delta[e[0]]++
- delta[e[1]]--
+ d[e[0]]++
+ d[e[1]]--
+ }
+
+ keys := make([]int, 0, len(d))
+ for k := range d {
+ keys = append(keys, k)
}
- for i := 1; i < n; i++ {
- delta[i] += delta[i-1]
+ sort.Ints(keys)
+
+ s := 0
+ for _, k := range keys {
+ s += d[k]
+ ans = max(ans, s)
}
- return slices.Max(delta)
+ return
+}
+```
+
+#### TypeScript
+
+```ts
+function minMeetingRooms(intervals: number[][]): number {
+ const d: { [key: number]: number } = {};
+ for (const [l, r] of intervals) {
+ d[l] = (d[l] || 0) + 1;
+ d[r] = (d[r] || 0) - 1;
+ }
+
+ let [ans, s] = [0, 0];
+ const keys = Object.keys(d)
+ .map(Number)
+ .sort((a, b) => a - b);
+ for (const k of keys) {
+ s += d[k];
+ ans = Math.max(ans, s);
+ }
+ return ans;
}
```
#### Rust
```rust
-use std::{cmp::Reverse, collections::BinaryHeap};
+use std::collections::HashMap;
impl Solution {
- #[allow(dead_code)]
pub fn min_meeting_rooms(intervals: Vec>) -> i32 {
- // The min heap that stores the earliest ending time among all meeting rooms
- let mut pq = BinaryHeap::new();
- let mut intervals = intervals;
- let n = intervals.len();
-
- // Let's first sort the intervals vector
- intervals.sort_by(|lhs, rhs| lhs[0].cmp(&rhs[0]));
-
- // Push the first end time to the heap
- pq.push(Reverse(intervals[0][1]));
-
- // Traverse the intervals vector
- for i in 1..n {
- // Get the current top element from the heap
- if let Some(Reverse(end_time)) = pq.pop() {
- if end_time <= intervals[i][0] {
- // If the end time is early than the current begin time
- let new_end_time = intervals[i][1];
- pq.push(Reverse(new_end_time));
- } else {
- // Otherwise, push the end time back and we also need a new room
- pq.push(Reverse(end_time));
- pq.push(Reverse(intervals[i][1]));
- }
- }
+ let mut d: HashMap = HashMap::new();
+ for interval in intervals {
+ let (l, r) = (interval[0], interval[1]);
+ *d.entry(l).or_insert(0) += 1;
+ *d.entry(r).or_insert(0) -= 1;
+ }
+
+ let mut times: Vec = d.keys().cloned().collect();
+ times.sort();
+
+ let mut ans = 0;
+ let mut s = 0;
+ for time in times {
+ s += d[&time];
+ ans = ans.max(s);
}
- pq.len() as i32
+ ans
}
}
```
diff --git a/solution/0200-0299/0253.Meeting Rooms II/README_EN.md b/solution/0200-0299/0253.Meeting Rooms II/README_EN.md
index 819e7009ce22e..9065c37a97deb 100644
--- a/solution/0200-0299/0253.Meeting Rooms II/README_EN.md
+++ b/solution/0200-0299/0253.Meeting Rooms II/README_EN.md
@@ -45,7 +45,170 @@ tags:
-### Solution 1
+### Solution 1: Difference Array
+
+We can implement this using a difference array.
+
+First, we find the maximum end time of all the meetings, denoted as $m$. Then, we create a difference array $d$ of length $m + 1$. For each meeting, we add to the corresponding positions in the difference array: $d[l] = d[l] + 1$ for the start time, and $d[r] = d[r] - 1$ for the end time.
+
+Next, we calculate the prefix sum of the difference array and find the maximum value of the prefix sum, which represents the minimum number of meeting rooms required.
+
+The time complexity is $O(n + m)$ and the space complexity is $O(m)$, where $n$ is the number of meetings and $m$ is the maximum end time.
+
+
+
+#### Python3
+
+```python
+class Solution:
+ def minMeetingRooms(self, intervals: List[List[int]]) -> int:
+ m = max(e[1] for e in intervals)
+ d = [0] * (m + 1)
+ for l, r in intervals:
+ d[l] += 1
+ d[r] -= 1
+ ans = s = 0
+ for v in d:
+ s += v
+ ans = max(ans, s)
+ return ans
+```
+
+#### Java
+
+```java
+class Solution {
+ public int minMeetingRooms(int[][] intervals) {
+ int m = 0;
+ for (var e : intervals) {
+ m = Math.max(m, e[1]);
+ }
+ int[] d = new int[m + 1];
+ for (var e : intervals) {
+ ++d[e[0]];
+ --d[e[1]];
+ }
+ int ans = 0, s = 0;
+ for (int v : d) {
+ s += v;
+ ans = Math.max(ans, s);
+ }
+ return ans;
+ }
+}
+```
+
+#### C++
+
+```cpp
+class Solution {
+public:
+ int minMeetingRooms(vector>& intervals) {
+ int m = 0;
+ for (const auto& e : intervals) {
+ m = max(m, e[1]);
+ }
+ vector d(m + 1);
+ for (const auto& e : intervals) {
+ d[e[0]]++;
+ d[e[1]]--;
+ }
+ int ans = 0, s = 0;
+ for (int v : d) {
+ s += v;
+ ans = max(ans, s);
+ }
+ return ans;
+ }
+};
+```
+
+#### Go
+
+```go
+func minMeetingRooms(intervals [][]int) (ans int) {
+ m := 0
+ for _, e := range intervals {
+ m = max(m, e[1])
+ }
+
+ d := make([]int, m+1)
+ for _, e := range intervals {
+ d[e[0]]++
+ d[e[1]]--
+ }
+
+ s := 0
+ for _, v := range d {
+ s += v
+ ans = max(ans, s)
+ }
+ return
+}
+```
+
+#### TypeScript
+
+```ts
+function minMeetingRooms(intervals: number[][]): number {
+ const m = Math.max(...intervals.map(([_, r]) => r));
+ const d: number[] = Array(m + 1).fill(0);
+ for (const [l, r] of intervals) {
+ d[l]++;
+ d[r]--;
+ }
+ let [ans, s] = [0, 0];
+ for (const v of d) {
+ s += v;
+ ans = Math.max(ans, s);
+ }
+ return ans;
+}
+```
+
+#### Rust
+
+```rust
+impl Solution {
+ pub fn min_meeting_rooms(intervals: Vec>) -> i32 {
+ let mut m = 0;
+ for e in &intervals {
+ m = m.max(e[1]);
+ }
+
+ let mut d = vec![0; (m + 1) as usize];
+ for e in intervals {
+ d[e[0] as usize] += 1;
+ d[e[1] as usize] -= 1;
+ }
+
+ let mut ans = 0;
+ let mut s = 0;
+ for v in d {
+ s += v;
+ ans = ans.max(s);
+ }
+
+ ans
+ }
+}
+```
+
+
+
+
+
+
+
+### Solution 2: Difference (Hash Map)
+
+If the meeting times span a large range, we can use a hash map instead of a difference array.
+
+First, we create a hash map $d$, where we add to the corresponding positions for each meeting's start time and end time: $d[l] = d[l] + 1$ for the start time, and $d[r] = d[r] - 1$ for the end time.
+
+Then, we sort the hash map by its keys, calculate the prefix sum of the hash map, and find the maximum value of the prefix sum, which represents the minimum number of meeting rooms required.
+
+The time complexity is $O(n \times \log n)$ and the space complexity is $O(n)$, where $n$ is the number of meetings.
@@ -54,11 +217,15 @@ tags:
```python
class Solution:
def minMeetingRooms(self, intervals: List[List[int]]) -> int:
- delta = [0] * 1000010
- for start, end in intervals:
- delta[start] += 1
- delta[end] -= 1
- return max(accumulate(delta))
+ d = defaultdict(int)
+ for l, r in intervals:
+ d[l] += 1
+ d[r] -= 1
+ ans = s = 0
+ for _, v in sorted(d.items()):
+ s += v
+ ans = max(ans, s)
+ return ans
```
#### Java
@@ -66,18 +233,17 @@ class Solution:
```java
class Solution {
public int minMeetingRooms(int[][] intervals) {
- int n = 1000010;
- int[] delta = new int[n];
- for (int[] e : intervals) {
- ++delta[e[0]];
- --delta[e[1]];
+ Map d = new TreeMap<>();
+ for (var e : intervals) {
+ d.merge(e[0], 1, Integer::sum);
+ d.merge(e[1], -1, Integer::sum);
}
- int res = delta[0];
- for (int i = 1; i < n; ++i) {
- delta[i] += delta[i - 1];
- res = Math.max(res, delta[i]);
+ int ans = 0, s = 0;
+ for (var e : d.values()) {
+ s += e;
+ ans = Math.max(ans, s);
}
- return res;
+ return ans;
}
}
```
@@ -88,16 +254,17 @@ class Solution {
class Solution {
public:
int minMeetingRooms(vector>& intervals) {
- int n = 1000010;
- vector