diff --git a/solution/2300-2399/2397.Maximum Rows Covered by Columns/README.md b/solution/2300-2399/2397.Maximum Rows Covered by Columns/README.md index dbdb1cfae87fa..d1295c38660ca 100644 --- a/solution/2300-2399/2397.Maximum Rows Covered by Columns/README.md +++ b/solution/2300-2399/2397.Maximum Rows Covered by Columns/README.md @@ -70,7 +70,7 @@ **方法一:二进制枚举** -我们先将矩阵中的每一行转换成一个二进制数,记录在数组 $rows$ 中,其中 $rows[i]$ 表示第 $i$ 行对应的二进制数,而 $rows[i]$ 的第 $j$ 位表示第 $i$ 行第 $j$ 列的值。 +我们先将矩阵中的每一行转换成一个二进制数,记录在数组 $rows$ 中,其中 $rows[i]$ 表示第 $i$ 行对应的二进制数,而 $rows[i]$ 这个二进制数的第 $j$ 位表示第 $i$ 行第 $j$ 列的值。 接下来,我们枚举所有的 $2^n$ 种列选择方案,其中 $n$ 为矩阵的列数。对于每一种列选择方案,我们判断是否选中了 `numSelect` 列,如果不是,则跳过。否则,我们统计矩阵中有多少行中的所有 $1$ 都被选中的列覆盖,即统计有多少行的二进制数 $rows[i]$ 与列选择方案 $mask$ 按位与的结果等于 $rows[i]$,并更新最大的行数。 @@ -199,7 +199,40 @@ func maximumRows(matrix [][]int, numSelect int) (ans int) { ### **TypeScript** ```ts +function maximumRows(matrix: number[][], numSelect: number): number { + const [m, n] = [matrix.length, matrix[0].length]; + const rows: number[] = Array(m).fill(0); + for (let i = 0; i < m; ++i) { + for (let j = 0; j < n; ++j) { + if (matrix[i][j]) { + rows[i] |= 1 << j; + } + } + } + let ans = 0; + for (let mask = 1; mask < 1 << n; ++mask) { + if (bitCount(mask) !== numSelect) { + continue; + } + let t = 0; + for (const x of rows) { + if ((x & mask) === x) { + ++t; + } + } + ans = Math.max(ans, t); + } + return ans; +} +function bitCount(i: number): number { + i = i - ((i >>> 1) & 0x55555555); + i = (i & 0x33333333) + ((i >>> 2) & 0x33333333); + i = (i + (i >>> 4)) & 0x0f0f0f0f; + i = i + (i >>> 8); + i = i + (i >>> 16); + return i & 0x3f; +} ``` ### **...** diff --git a/solution/2300-2399/2397.Maximum Rows Covered by Columns/README_EN.md b/solution/2300-2399/2397.Maximum Rows Covered by Columns/README_EN.md index 7623681ab1a49..0b3ba2a5d4aaa 100644 --- a/solution/2300-2399/2397.Maximum Rows Covered by Columns/README_EN.md +++ b/solution/2300-2399/2397.Maximum Rows Covered by Columns/README_EN.md @@ -55,6 +55,14 @@ Therefore, we return 2. ## Solutions +**Solution 1: Binary Enumeration** + +First, we convert each row of the matrix into a binary number and record it in the array $rows$. Here, $rows[i]$ represents the binary number corresponding to the $i$-th row, and the $j$-th bit of this binary number $rows[i]$ represents the value of the $i$-th row and $j$-th column. + +Next, we enumerate all $2^n$ column selection schemes, where $n$ is the number of columns in the matrix. For each column selection scheme, we check whether `numSelect` columns have been selected. If not, we skip it. Otherwise, we count how many rows in the matrix are covered by the selected columns, i.e., how many binary numbers $rows[i]$ are equal to the bitwise AND of $rows[i]$ and the column selection scheme $mask$. We then update the maximum number of rows. + +The time complexity is $O(2^n \times m)$, and the space complexity is $O(m)$. Where $m$ and $n$ are the number of rows and columns in the matrix, respectively. + ### **Python3** @@ -174,7 +182,40 @@ func maximumRows(matrix [][]int, numSelect int) (ans int) { ### **TypeScript** ```ts +function maximumRows(matrix: number[][], numSelect: number): number { + const [m, n] = [matrix.length, matrix[0].length]; + const rows: number[] = Array(m).fill(0); + for (let i = 0; i < m; ++i) { + for (let j = 0; j < n; ++j) { + if (matrix[i][j]) { + rows[i] |= 1 << j; + } + } + } + let ans = 0; + for (let mask = 1; mask < 1 << n; ++mask) { + if (bitCount(mask) !== numSelect) { + continue; + } + let t = 0; + for (const x of rows) { + if ((x & mask) === x) { + ++t; + } + } + ans = Math.max(ans, t); + } + return ans; +} +function bitCount(i: number): number { + i = i - ((i >>> 1) & 0x55555555); + i = (i & 0x33333333) + ((i >>> 2) & 0x33333333); + i = (i + (i >>> 4)) & 0x0f0f0f0f; + i = i + (i >>> 8); + i = i + (i >>> 16); + return i & 0x3f; +} ``` ### **...** diff --git a/solution/2300-2399/2397.Maximum Rows Covered by Columns/Solution.ts b/solution/2300-2399/2397.Maximum Rows Covered by Columns/Solution.ts new file mode 100644 index 0000000000000..c2ace19ebfe44 --- /dev/null +++ b/solution/2300-2399/2397.Maximum Rows Covered by Columns/Solution.ts @@ -0,0 +1,34 @@ +function maximumRows(matrix: number[][], numSelect: number): number { + const [m, n] = [matrix.length, matrix[0].length]; + const rows: number[] = Array(m).fill(0); + for (let i = 0; i < m; ++i) { + for (let j = 0; j < n; ++j) { + if (matrix[i][j]) { + rows[i] |= 1 << j; + } + } + } + let ans = 0; + for (let mask = 1; mask < 1 << n; ++mask) { + if (bitCount(mask) !== numSelect) { + continue; + } + let t = 0; + for (const x of rows) { + if ((x & mask) === x) { + ++t; + } + } + ans = Math.max(ans, t); + } + return ans; +} + +function bitCount(i: number): number { + i = i - ((i >>> 1) & 0x55555555); + i = (i & 0x33333333) + ((i >>> 2) & 0x33333333); + i = (i + (i >>> 4)) & 0x0f0f0f0f; + i = i + (i >>> 8); + i = i + (i >>> 16); + return i & 0x3f; +} diff --git a/solution/2300-2399/2398.Maximum Number of Robots Within Budget/Solutio.py b/solution/2300-2399/2398.Maximum Number of Robots Within Budget/Solution.py similarity index 97% rename from solution/2300-2399/2398.Maximum Number of Robots Within Budget/Solutio.py rename to solution/2300-2399/2398.Maximum Number of Robots Within Budget/Solution.py index 122f1522c478d..aafdc27a364ea 100644 --- a/solution/2300-2399/2398.Maximum Number of Robots Within Budget/Solutio.py +++ b/solution/2300-2399/2398.Maximum Number of Robots Within Budget/Solution.py @@ -1,18 +1,18 @@ -class Solution: - def maximumRobots( - self, chargeTimes: List[int], runningCosts: List[int], budget: int - ) -> int: - q = deque() - ans = j = s = 0 - for i, (a, b) in enumerate(zip(chargeTimes, runningCosts)): - while q and chargeTimes[q[-1]] <= a: - q.pop() - q.append(i) - s += b - while q and chargeTimes[q[0]] + (i - j + 1) * s > budget: - if q[0] == j: - q.popleft() - s -= runningCosts[j] - j += 1 - ans = max(ans, i - j + 1) - return ans +class Solution: + def maximumRobots( + self, chargeTimes: List[int], runningCosts: List[int], budget: int + ) -> int: + q = deque() + ans = j = s = 0 + for i, (a, b) in enumerate(zip(chargeTimes, runningCosts)): + while q and chargeTimes[q[-1]] <= a: + q.pop() + q.append(i) + s += b + while q and chargeTimes[q[0]] + (i - j + 1) * s > budget: + if q[0] == j: + q.popleft() + s -= runningCosts[j] + j += 1 + ans = max(ans, i - j + 1) + return ans diff --git a/solution/2400-2499/2487.Remove Nodes From Linked List/README.md b/solution/2400-2499/2487.Remove Nodes From Linked List/README.md index b2460f49a0ca8..17d8d57f4a7a5 100644 --- a/solution/2400-2499/2487.Remove Nodes From Linked List/README.md +++ b/solution/2400-2499/2487.Remove Nodes From Linked List/README.md @@ -50,9 +50,11 @@ **方法一:单调栈模拟** -我们可以先将链表中的节点值存入数组,然后遍历数组,维护一个从栈底到栈顶单调递减的栈,如果当前元素比栈顶元素大,则将栈顶元素出栈,直到当前元素小于等于栈顶元素,将当前元素入栈。最后将栈中的元素逆序,构造得到的链表即为答案。 +我们可以先将链表中的节点值存入数组 $nums$,然后遍历数组 $nums$,维护一个从栈底到栈顶单调递减的栈 $stk$,如果当前元素比栈顶元素大,则将栈顶元素出栈,直到当前元素小于等于栈顶元素,将当前元素入栈。 -时间复杂度为 $O(n)$,空间复杂度为 $O(n)$。 +最后,我们从栈底到栈顶构造出结果链表,即为答案。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是链表的长度。 @@ -109,15 +111,15 @@ class Solution { } Deque stk = new ArrayDeque<>(); for (int v : nums) { - while (!stk.isEmpty() && stk.peek() < v) { - stk.pop(); + while (!stk.isEmpty() && stk.peekLast() < v) { + stk.pollLast(); } - stk.push(v); + stk.offerLast(v); } ListNode dummy = new ListNode(); head = dummy; while (!stk.isEmpty()) { - head.next = new ListNode(stk.pollLast()); + head.next = new ListNode(stk.pollFirst()); head = head.next; } return dummy.next; @@ -197,6 +199,43 @@ func removeNodes(head *ListNode) *ListNode { } ``` +### **TypeScript** + +```ts +/** + * Definition for singly-linked list. + * class ListNode { + * val: number + * next: ListNode | null + * constructor(val?: number, next?: ListNode | null) { + * this.val = (val===undefined ? 0 : val) + * this.next = (next===undefined ? null : next) + * } + * } + */ + +function removeNodes(head: ListNode | null): ListNode | null { + const nums = []; + for (; head; head = head.next) { + nums.push(head.val); + } + const stk: number[] = []; + for (const v of nums) { + while (stk.length && stk.at(-1)! < v) { + stk.pop(); + } + stk.push(v); + } + const dummy = new ListNode(); + head = dummy; + for (const v of stk) { + head.next = new ListNode(v); + head = head.next; + } + return dummy.next; +} +``` + ### **...** ``` diff --git a/solution/2400-2499/2487.Remove Nodes From Linked List/README_EN.md b/solution/2400-2499/2487.Remove Nodes From Linked List/README_EN.md index debd523f5d462..9a50373f14f20 100644 --- a/solution/2400-2499/2487.Remove Nodes From Linked List/README_EN.md +++ b/solution/2400-2499/2487.Remove Nodes From Linked List/README_EN.md @@ -40,6 +40,14 @@ ## Solutions +**Solution 1: Monotonic Stack Simulation** + +We can first store the node values of the linked list into an array $nums$. Then, we traverse the array $nums$, maintaining a stack $stk$ that is monotonically decreasing from the bottom to the top. If the current element is larger than the top element of the stack, we pop the top element of the stack until the current element is less than or equal to the top element, and then we push the current element into the stack. + +Finally, we construct the resulting linked list from the bottom to the top of the stack, which is the answer. + +The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of the linked list. + ### **Python3** @@ -91,15 +99,15 @@ class Solution { } Deque stk = new ArrayDeque<>(); for (int v : nums) { - while (!stk.isEmpty() && stk.peek() < v) { - stk.pop(); + while (!stk.isEmpty() && stk.peekLast() < v) { + stk.pollLast(); } - stk.push(v); + stk.offerLast(v); } ListNode dummy = new ListNode(); head = dummy; while (!stk.isEmpty()) { - head.next = new ListNode(stk.pollLast()); + head.next = new ListNode(stk.pollFirst()); head = head.next; } return dummy.next; @@ -179,6 +187,43 @@ func removeNodes(head *ListNode) *ListNode { } ``` +### **TypeScript** + +```ts +/** + * Definition for singly-linked list. + * class ListNode { + * val: number + * next: ListNode | null + * constructor(val?: number, next?: ListNode | null) { + * this.val = (val===undefined ? 0 : val) + * this.next = (next===undefined ? null : next) + * } + * } + */ + +function removeNodes(head: ListNode | null): ListNode | null { + const nums = []; + for (; head; head = head.next) { + nums.push(head.val); + } + const stk: number[] = []; + for (const v of nums) { + while (stk.length && stk.at(-1)! < v) { + stk.pop(); + } + stk.push(v); + } + const dummy = new ListNode(); + head = dummy; + for (const v of stk) { + head.next = new ListNode(v); + head = head.next; + } + return dummy.next; +} +``` + ### **...** ``` diff --git a/solution/2400-2499/2487.Remove Nodes From Linked List/Solution.java b/solution/2400-2499/2487.Remove Nodes From Linked List/Solution.java index 74afc3b592c24..db2de45df6d50 100644 --- a/solution/2400-2499/2487.Remove Nodes From Linked List/Solution.java +++ b/solution/2400-2499/2487.Remove Nodes From Linked List/Solution.java @@ -1,33 +1,33 @@ -/** - * Definition for singly-linked list. - * public class ListNode { - * int val; - * ListNode next; - * ListNode() {} - * ListNode(int val) { this.val = val; } - * ListNode(int val, ListNode next) { this.val = val; this.next = next; } - * } - */ -class Solution { - public ListNode removeNodes(ListNode head) { - List nums = new ArrayList<>(); - while (head != null) { - nums.add(head.val); - head = head.next; - } - Deque stk = new ArrayDeque<>(); - for (int v : nums) { - while (!stk.isEmpty() && stk.peek() < v) { - stk.pop(); - } - stk.push(v); - } - ListNode dummy = new ListNode(); - head = dummy; - while (!stk.isEmpty()) { - head.next = new ListNode(stk.pollLast()); - head = head.next; - } - return dummy.next; - } +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ +class Solution { + public ListNode removeNodes(ListNode head) { + List nums = new ArrayList<>(); + while (head != null) { + nums.add(head.val); + head = head.next; + } + Deque stk = new ArrayDeque<>(); + for (int v : nums) { + while (!stk.isEmpty() && stk.peekLast() < v) { + stk.pollLast(); + } + stk.offerLast(v); + } + ListNode dummy = new ListNode(); + head = dummy; + while (!stk.isEmpty()) { + head.next = new ListNode(stk.pollFirst()); + head = head.next; + } + return dummy.next; + } } \ No newline at end of file diff --git a/solution/2400-2499/2487.Remove Nodes From Linked List/Solution.ts b/solution/2400-2499/2487.Remove Nodes From Linked List/Solution.ts new file mode 100644 index 0000000000000..04fdb565be8b5 --- /dev/null +++ b/solution/2400-2499/2487.Remove Nodes From Linked List/Solution.ts @@ -0,0 +1,32 @@ +/** + * Definition for singly-linked list. + * class ListNode { + * val: number + * next: ListNode | null + * constructor(val?: number, next?: ListNode | null) { + * this.val = (val===undefined ? 0 : val) + * this.next = (next===undefined ? null : next) + * } + * } + */ + +function removeNodes(head: ListNode | null): ListNode | null { + const nums = []; + for (; head; head = head.next) { + nums.push(head.val); + } + const stk: number[] = []; + for (const v of nums) { + while (stk.length && stk.at(-1)! < v) { + stk.pop(); + } + stk.push(v); + } + const dummy = new ListNode(); + head = dummy; + for (const v of stk) { + head.next = new ListNode(v); + head = head.next; + } + return dummy.next; +} diff --git a/solution/2900-2999/2980.Check if Bitwise OR Has Trailing Zeros/README.md b/solution/2900-2999/2980.Check if Bitwise OR Has Trailing Zeros/README.md index 27c66d6df0c1a..dd714536afff4 100644 --- a/solution/2900-2999/2980.Check if Bitwise OR Has Trailing Zeros/README.md +++ b/solution/2900-2999/2980.Check if Bitwise OR Has Trailing Zeros/README.md @@ -54,6 +54,12 @@ +**方法一:统计偶数个数** + +根据题意,我们可以知道,如果数组中存在两个或两个以上的元素,其按位或运算结果存在尾随零,那么数组中必然存在至少两个偶数。因此,我们可以统计数组中偶数的个数,如果偶数的个数大于等于 $2$,那么就返回 `true`,否则返回 `false`。 + +时间复杂度 $O(n)$,其中 $n$ 是数组的长度。空间复杂度 $O(1)$。 + ### **Python3** @@ -61,7 +67,9 @@ ```python - +class Solution: + def hasTrailingZeros(self, nums: List[int]) -> bool: + return sum(x & 1 ^ 1 for x in nums) >= 2 ``` ### **Java** @@ -69,19 +77,54 @@ ```java - +class Solution { + public boolean hasTrailingZeros(int[] nums) { + int cnt = 0; + for (int x : nums) { + cnt += (x & 1 ^ 1); + } + return cnt >= 2; + } +} ``` ### **C++** ```cpp - +class Solution { +public: + bool hasTrailingZeros(vector& nums) { + int cnt = 0; + for (int x : nums) { + cnt += (x & 1 ^ 1); + } + return cnt >= 2; + } +}; ``` ### **Go** ```go +func hasTrailingZeros(nums []int) bool { + cnt := 0 + for _, x := range nums { + cnt += (x&1 ^ 1) + } + return cnt >= 2 +} +``` + +### **TypeScript** +```ts +function hasTrailingZeros(nums: number[]): boolean { + let cnt = 0; + for (const x of nums) { + cnt += (x & 1) ^ 1; + } + return cnt >= 2; +} ``` ### **...** diff --git a/solution/2900-2999/2980.Check if Bitwise OR Has Trailing Zeros/README_EN.md b/solution/2900-2999/2980.Check if Bitwise OR Has Trailing Zeros/README_EN.md index 7dd5267ad309d..752103cf6f8c6 100644 --- a/solution/2900-2999/2980.Check if Bitwise OR Has Trailing Zeros/README_EN.md +++ b/solution/2900-2999/2980.Check if Bitwise OR Has Trailing Zeros/README_EN.md @@ -48,30 +48,73 @@ Other possible ways to select elements to have trailing zeroes in the binary rep ## Solutions +**Solution 1: Counting Even Numbers** + +According to the problem statement, if there are two or more elements in the array whose bitwise OR operation results in trailing zeros, then there must be at least two even numbers in the array. Therefore, we can count the number of even numbers in the array. If the count of even numbers is greater than or equal to $2$, then return `true`, otherwise return `false`. + +The time complexity is $O(n)$, where $n$ is the length of the array. The space complexity is $O(1)$. + ### **Python3** ```python - +class Solution: + def hasTrailingZeros(self, nums: List[int]) -> bool: + return sum(x & 1 ^ 1 for x in nums) >= 2 ``` ### **Java** ```java - +class Solution { + public boolean hasTrailingZeros(int[] nums) { + int cnt = 0; + for (int x : nums) { + cnt += (x & 1 ^ 1); + } + return cnt >= 2; + } +} ``` ### **C++** ```cpp - +class Solution { +public: + bool hasTrailingZeros(vector& nums) { + int cnt = 0; + for (int x : nums) { + cnt += (x & 1 ^ 1); + } + return cnt >= 2; + } +}; ``` ### **Go** ```go +func hasTrailingZeros(nums []int) bool { + cnt := 0 + for _, x := range nums { + cnt += (x&1 ^ 1) + } + return cnt >= 2 +} +``` + +### **TypeScript** +```ts +function hasTrailingZeros(nums: number[]): boolean { + let cnt = 0; + for (const x of nums) { + cnt += (x & 1) ^ 1; + } + return cnt >= 2; +} ``` ### **...** diff --git a/solution/2900-2999/2980.Check if Bitwise OR Has Trailing Zeros/Solution.cpp b/solution/2900-2999/2980.Check if Bitwise OR Has Trailing Zeros/Solution.cpp new file mode 100644 index 0000000000000..8257e8c083c03 --- /dev/null +++ b/solution/2900-2999/2980.Check if Bitwise OR Has Trailing Zeros/Solution.cpp @@ -0,0 +1,10 @@ +class Solution { +public: + bool hasTrailingZeros(vector& nums) { + int cnt = 0; + for (int x : nums) { + cnt += (x & 1 ^ 1); + } + return cnt >= 2; + } +}; \ No newline at end of file diff --git a/solution/2900-2999/2980.Check if Bitwise OR Has Trailing Zeros/Solution.go b/solution/2900-2999/2980.Check if Bitwise OR Has Trailing Zeros/Solution.go new file mode 100644 index 0000000000000..34a95bbedd24e --- /dev/null +++ b/solution/2900-2999/2980.Check if Bitwise OR Has Trailing Zeros/Solution.go @@ -0,0 +1,7 @@ +func hasTrailingZeros(nums []int) bool { + cnt := 0 + for _, x := range nums { + cnt += (x&1 ^ 1) + } + return cnt >= 2 +} \ No newline at end of file diff --git a/solution/2900-2999/2980.Check if Bitwise OR Has Trailing Zeros/Solution.java b/solution/2900-2999/2980.Check if Bitwise OR Has Trailing Zeros/Solution.java new file mode 100644 index 0000000000000..25892ae7c2829 --- /dev/null +++ b/solution/2900-2999/2980.Check if Bitwise OR Has Trailing Zeros/Solution.java @@ -0,0 +1,9 @@ +class Solution { + public boolean hasTrailingZeros(int[] nums) { + int cnt = 0; + for (int x : nums) { + cnt += (x & 1 ^ 1); + } + return cnt >= 2; + } +} \ No newline at end of file diff --git a/solution/2900-2999/2980.Check if Bitwise OR Has Trailing Zeros/Solution.py b/solution/2900-2999/2980.Check if Bitwise OR Has Trailing Zeros/Solution.py new file mode 100644 index 0000000000000..a8cb97dc8967d --- /dev/null +++ b/solution/2900-2999/2980.Check if Bitwise OR Has Trailing Zeros/Solution.py @@ -0,0 +1,3 @@ +class Solution: + def hasTrailingZeros(self, nums: List[int]) -> bool: + return sum(x & 1 ^ 1 for x in nums) >= 2 diff --git a/solution/2900-2999/2980.Check if Bitwise OR Has Trailing Zeros/Solution.ts b/solution/2900-2999/2980.Check if Bitwise OR Has Trailing Zeros/Solution.ts new file mode 100644 index 0000000000000..540655c95896e --- /dev/null +++ b/solution/2900-2999/2980.Check if Bitwise OR Has Trailing Zeros/Solution.ts @@ -0,0 +1,7 @@ +function hasTrailingZeros(nums: number[]): boolean { + let cnt = 0; + for (const x of nums) { + cnt += (x & 1) ^ 1; + } + return cnt >= 2; +} diff --git a/solution/2900-2999/2981.Find Longest Special Substring That Occurs Thrice I/README.md b/solution/2900-2999/2981.Find Longest Special Substring That Occurs Thrice I/README.md index 6b987e08843ef..597e9c51e2a03 100644 --- a/solution/2900-2999/2981.Find Longest Special Substring That Occurs Thrice I/README.md +++ b/solution/2900-2999/2981.Find Longest Special Substring That Occurs Thrice I/README.md @@ -55,6 +55,20 @@ +**方法一:二分查找 + 滑动窗口计数** + +我们注意到,如果一个长度为 $x$ 且出现至少三次的特殊子字符串存在,那么长度为 $x-1$ 的特殊子字符串也一定存在,这存在着单调性,因此我们可以使用二分查找的方法来找到最长的特殊子字符串。 + +我们定义二分查找的左边界 $l = 0$,右边界 $r = n$,其中 $n$ 是字符串的长度。每次二分查找的过程中,我们取 $mid = \lfloor \frac{l + r + 1}{2} \rfloor$,如果长度为 $mid$ 的特殊子字符串存在,那么我们就将左边界更新为 $mid$,否则我们就将右边界更新为 $mid - 1$。在二分查找的过程中,我们使用滑动窗口来计算特殊子字符串的个数。 + +具体地,我们设计一个函数 $check(x)$,表示长度为 $x$ 且出现至少三次的特殊子字符串是否存在。 + +在函数 $check(x)$ 中,我们定义一个哈希表或长度为 $26$ 的数组 $cnt$,其中 $cnt[i]$ 表示长度为 $x$,且由第 $i$ 个小写字母组成的特殊子字符串的个数。我们遍历字符串 $s$,如果当前遍历到的字符为 $s[i]$,那么我们将指针 $j$ 向右移动,直到 $s[j] \neq s[i]$,此时 $s[i \cdots j-1]$ 就是一个长度为 $x$ 的特殊子字符串,我们将 $cnt[s[i]]$ 增加 $\max(0, j - i - x + 1)$,然后将指针 $i$ 更新为 $j$。 + +在遍历结束之后,我们遍历数组 $cnt$,如果存在 $cnt[i] \geq 3$,那么就说明长度为 $x$ 且出现至少三次的特殊子字符串存在,我们返回 $true$,否则返回 $false$。 + +时间复杂度 $O((n + |\Sigma|) \times \log n)$,空间复杂度 $O(|\Sigma|)$,其中 $n$ 是字符串 $s$ 的长度,而 $|\Sigma|$ 表示字符集的大小,本题中字符集为小写英文字母,因此 $|\Sigma| = 26$。 + ### **Python3** @@ -62,7 +76,28 @@ ```python - +class Solution: + def maximumLength(self, s: str) -> int: + def check(x: int) -> bool: + cnt = defaultdict(int) + i = 0 + while i < n: + j = i + 1 + while j < n and s[j] == s[i]: + j += 1 + cnt[s[i]] += max(0, j - i - x + 1) + i = j + return max(cnt.values()) >= 3 + + n = len(s) + l, r = 0, n + while l < r: + mid = (l + r + 1) >> 1 + if check(mid): + l = mid + else: + r = mid - 1 + return -1 if l == 0 else l ``` ### **Java** @@ -70,19 +105,150 @@ ```java - +class Solution { + private String s; + private int n; + + public int maximumLength(String s) { + this.s = s; + n = s.length(); + int l = 0, r = n; + while (l < r) { + int mid = (l + r + 1) >> 1; + if (check(mid)) { + l = mid; + } else { + r = mid - 1; + } + } + return l == 0 ? -1 : l; + } + + private boolean check(int x) { + int[] cnt = new int[26]; + for (int i = 0; i < n;) { + int j = i + 1; + while (j < n && s.charAt(j) == s.charAt(i)) { + j++; + } + int k = s.charAt(i) - 'a'; + cnt[k] += Math.max(0, j - i - x + 1); + if (cnt[k] >= 3) { + return true; + } + i = j; + } + return false; + } +} ``` ### **C++** ```cpp - +class Solution { +public: + int maximumLength(string s) { + int n = s.size(); + int l = 0, r = n; + auto check = [&](int x) { + int cnt[26]{}; + for (int i = 0; i < n;) { + int j = i + 1; + while (j < n && s[j] == s[i]) { + ++j; + } + int k = s[i] - 'a'; + cnt[k] += max(0, j - i - x + 1); + if (cnt[k] >= 3) { + return true; + } + i = j; + } + return false; + }; + while (l < r) { + int mid = (l + r + 1) >> 1; + if (check(mid)) { + l = mid; + } else { + r = mid - 1; + } + } + return l == 0 ? -1 : l; + } +}; ``` ### **Go** ```go +func maximumLength(s string) int { + n := len(s) + l, r := 0, n + check := func(x int) bool { + cnt := [26]int{} + for i := 0; i < n; { + j := i + 1 + for j < n && s[j] == s[i] { + j++ + } + k := s[i] - 'a' + cnt[k] += max(0, j-i-x+1) + if cnt[k] >= 3 { + return true + } + i = j + } + return false + } + for l < r { + mid := (l + r + 1) >> 1 + if check(mid) { + l = mid + } else { + r = mid - 1 + } + } + if l == 0 { + return -1 + } + return l +} +``` +### **TypeScript** + +```ts +function maximumLength(s: string): number { + const n = s.length; + let [l, r] = [0, n]; + const check = (x: number): boolean => { + const cnt: number[] = Array(26).fill(0); + for (let i = 0; i < n; ) { + let j = i + 1; + while (j < n && s[j] === s[i]) { + j++; + } + const k = s[i].charCodeAt(0) - 'a'.charCodeAt(0); + cnt[k] += Math.max(0, j - i - x + 1); + if (cnt[k] >= 3) { + return true; + } + i = j; + } + return false; + }; + while (l < r) { + const mid = (l + r + 1) >> 1; + if (check(mid)) { + l = mid; + } else { + r = mid - 1; + } + } + return l === 0 ? -1 : l; +} ``` ### **...** diff --git a/solution/2900-2999/2981.Find Longest Special Substring That Occurs Thrice I/README_EN.md b/solution/2900-2999/2981.Find Longest Special Substring That Occurs Thrice I/README_EN.md index f221e26197b21..47e8831897ead 100644 --- a/solution/2900-2999/2981.Find Longest Special Substring That Occurs Thrice I/README_EN.md +++ b/solution/2900-2999/2981.Find Longest Special Substring That Occurs Thrice I/README_EN.md @@ -49,30 +49,196 @@ It can be shown that the maximum length achievable is 1. ## Solutions +**Solution 1: Binary Search + Sliding Window Counting** + +We notice that if there exists a special substring of length $x$ that appears at least three times, then a special substring of length $x-1$ must also exist. This exhibits a monotonicity, so we can use binary search to find the longest special substring. + +We define the left boundary of the binary search as $l = 0$ and the right boundary as $r = n$, where $n$ is the length of the string. In each binary search, we take $mid = \lfloor \frac{l + r + 1}{2} \rfloor$. If a special substring of length $mid$ exists, we update the left boundary to $mid$. Otherwise, we update the right boundary to $mid - 1$. During the binary search, we use a sliding window to count the number of special substrings. + +Specifically, we design a function $check(x)$ to indicate whether a special substring of length $x$ that appears at least three times exists. + +In the function $check(x)$, we define a hash table or an array of length $26$ named $cnt$, where $cnt[i]$ represents the count of special substrings of length $x$ composed of the $i$-th lowercase letter. We traverse the string $s$. If the current character is $s[i]$, we move the pointer $j$ to the right until $s[j] \neq s[i]$. At this point, $s[i \cdots j-1]$ is a special substring of length $x$. We increase $cnt[s[i]]$ by $\max(0, j - i - x + 1)$, and then update the pointer $i$ to $j$. + +After the traversal, we go through the array $cnt$. If there exists $cnt[i] \geq 3$, it means a special substring of length $x$ that appears at least three times exists, so we return $true$. Otherwise, we return $false$. + +The time complexity is $O((n + |\Sigma|) \times \log n)$, and the space complexity is $O(|\Sigma|)$, where $n$ is the length of the string $s$, and $|\Sigma|$ represents the size of the character set. In this problem, the character set is lowercase English letters, so $|\Sigma| = 26$. + ### **Python3** ```python - +class Solution: + def maximumLength(self, s: str) -> int: + def check(x: int) -> bool: + cnt = defaultdict(int) + i = 0 + while i < n: + j = i + 1 + while j < n and s[j] == s[i]: + j += 1 + cnt[s[i]] += max(0, j - i - x + 1) + i = j + return max(cnt.values()) >= 3 + + n = len(s) + l, r = 0, n + while l < r: + mid = (l + r + 1) >> 1 + if check(mid): + l = mid + else: + r = mid - 1 + return -1 if l == 0 else l ``` ### **Java** ```java - +class Solution { + private String s; + private int n; + + public int maximumLength(String s) { + this.s = s; + n = s.length(); + int l = 0, r = n; + while (l < r) { + int mid = (l + r + 1) >> 1; + if (check(mid)) { + l = mid; + } else { + r = mid - 1; + } + } + return l == 0 ? -1 : l; + } + + private boolean check(int x) { + int[] cnt = new int[26]; + for (int i = 0; i < n;) { + int j = i + 1; + while (j < n && s.charAt(j) == s.charAt(i)) { + j++; + } + int k = s.charAt(i) - 'a'; + cnt[k] += Math.max(0, j - i - x + 1); + if (cnt[k] >= 3) { + return true; + } + i = j; + } + return false; + } +} ``` ### **C++** ```cpp - +class Solution { +public: + int maximumLength(string s) { + int n = s.size(); + int l = 0, r = n; + auto check = [&](int x) { + int cnt[26]{}; + for (int i = 0; i < n;) { + int j = i + 1; + while (j < n && s[j] == s[i]) { + ++j; + } + int k = s[i] - 'a'; + cnt[k] += max(0, j - i - x + 1); + if (cnt[k] >= 3) { + return true; + } + i = j; + } + return false; + }; + while (l < r) { + int mid = (l + r + 1) >> 1; + if (check(mid)) { + l = mid; + } else { + r = mid - 1; + } + } + return l == 0 ? -1 : l; + } +}; ``` ### **Go** ```go +func maximumLength(s string) int { + n := len(s) + l, r := 0, n + check := func(x int) bool { + cnt := [26]int{} + for i := 0; i < n; { + j := i + 1 + for j < n && s[j] == s[i] { + j++ + } + k := s[i] - 'a' + cnt[k] += max(0, j-i-x+1) + if cnt[k] >= 3 { + return true + } + i = j + } + return false + } + for l < r { + mid := (l + r + 1) >> 1 + if check(mid) { + l = mid + } else { + r = mid - 1 + } + } + if l == 0 { + return -1 + } + return l +} +``` +### **TypeScript** + +```ts +function maximumLength(s: string): number { + const n = s.length; + let [l, r] = [0, n]; + const check = (x: number): boolean => { + const cnt: number[] = Array(26).fill(0); + for (let i = 0; i < n; ) { + let j = i + 1; + while (j < n && s[j] === s[i]) { + j++; + } + const k = s[i].charCodeAt(0) - 'a'.charCodeAt(0); + cnt[k] += Math.max(0, j - i - x + 1); + if (cnt[k] >= 3) { + return true; + } + i = j; + } + return false; + }; + while (l < r) { + const mid = (l + r + 1) >> 1; + if (check(mid)) { + l = mid; + } else { + r = mid - 1; + } + } + return l === 0 ? -1 : l; +} ``` ### **...** diff --git a/solution/2900-2999/2981.Find Longest Special Substring That Occurs Thrice I/Solution.cpp b/solution/2900-2999/2981.Find Longest Special Substring That Occurs Thrice I/Solution.cpp new file mode 100644 index 0000000000000..cc67a747769d8 --- /dev/null +++ b/solution/2900-2999/2981.Find Longest Special Substring That Occurs Thrice I/Solution.cpp @@ -0,0 +1,32 @@ +class Solution { +public: + int maximumLength(string s) { + int n = s.size(); + int l = 0, r = n; + auto check = [&](int x) { + int cnt[26]{}; + for (int i = 0; i < n;) { + int j = i + 1; + while (j < n && s[j] == s[i]) { + ++j; + } + int k = s[i] - 'a'; + cnt[k] += max(0, j - i - x + 1); + if (cnt[k] >= 3) { + return true; + } + i = j; + } + return false; + }; + while (l < r) { + int mid = (l + r + 1) >> 1; + if (check(mid)) { + l = mid; + } else { + r = mid - 1; + } + } + return l == 0 ? -1 : l; + } +}; \ No newline at end of file diff --git a/solution/2900-2999/2981.Find Longest Special Substring That Occurs Thrice I/Solution.go b/solution/2900-2999/2981.Find Longest Special Substring That Occurs Thrice I/Solution.go new file mode 100644 index 0000000000000..94a47b6b03c98 --- /dev/null +++ b/solution/2900-2999/2981.Find Longest Special Substring That Occurs Thrice I/Solution.go @@ -0,0 +1,32 @@ +func maximumLength(s string) int { + n := len(s) + l, r := 0, n + check := func(x int) bool { + cnt := [26]int{} + for i := 0; i < n; { + j := i + 1 + for j < n && s[j] == s[i] { + j++ + } + k := s[i] - 'a' + cnt[k] += max(0, j-i-x+1) + if cnt[k] >= 3 { + return true + } + i = j + } + return false + } + for l < r { + mid := (l + r + 1) >> 1 + if check(mid) { + l = mid + } else { + r = mid - 1 + } + } + if l == 0 { + return -1 + } + return l +} \ No newline at end of file diff --git a/solution/2900-2999/2981.Find Longest Special Substring That Occurs Thrice I/Solution.java b/solution/2900-2999/2981.Find Longest Special Substring That Occurs Thrice I/Solution.java new file mode 100644 index 0000000000000..25f93a56fea62 --- /dev/null +++ b/solution/2900-2999/2981.Find Longest Special Substring That Occurs Thrice I/Solution.java @@ -0,0 +1,36 @@ +class Solution { + private String s; + private int n; + + public int maximumLength(String s) { + this.s = s; + n = s.length(); + int l = 0, r = n; + while (l < r) { + int mid = (l + r + 1) >> 1; + if (check(mid)) { + l = mid; + } else { + r = mid - 1; + } + } + return l == 0 ? -1 : l; + } + + private boolean check(int x) { + int[] cnt = new int[26]; + for (int i = 0; i < n;) { + int j = i + 1; + while (j < n && s.charAt(j) == s.charAt(i)) { + j++; + } + int k = s.charAt(i) - 'a'; + cnt[k] += Math.max(0, j - i - x + 1); + if (cnt[k] >= 3) { + return true; + } + i = j; + } + return false; + } +} \ No newline at end of file diff --git a/solution/2900-2999/2981.Find Longest Special Substring That Occurs Thrice I/Solution.py b/solution/2900-2999/2981.Find Longest Special Substring That Occurs Thrice I/Solution.py new file mode 100644 index 0000000000000..ce1b4f5856c5e --- /dev/null +++ b/solution/2900-2999/2981.Find Longest Special Substring That Occurs Thrice I/Solution.py @@ -0,0 +1,22 @@ +class Solution: + def maximumLength(self, s: str) -> int: + def check(x: int) -> bool: + cnt = defaultdict(int) + i = 0 + while i < n: + j = i + 1 + while j < n and s[j] == s[i]: + j += 1 + cnt[s[i]] += max(0, j - i - x + 1) + i = j + return max(cnt.values()) >= 3 + + n = len(s) + l, r = 0, n + while l < r: + mid = (l + r + 1) >> 1 + if check(mid): + l = mid + else: + r = mid - 1 + return -1 if l == 0 else l diff --git a/solution/2900-2999/2981.Find Longest Special Substring That Occurs Thrice I/Solution.ts b/solution/2900-2999/2981.Find Longest Special Substring That Occurs Thrice I/Solution.ts new file mode 100644 index 0000000000000..fdb8cab521ead --- /dev/null +++ b/solution/2900-2999/2981.Find Longest Special Substring That Occurs Thrice I/Solution.ts @@ -0,0 +1,29 @@ +function maximumLength(s: string): number { + const n = s.length; + let [l, r] = [0, n]; + const check = (x: number): boolean => { + const cnt: number[] = Array(26).fill(0); + for (let i = 0; i < n; ) { + let j = i + 1; + while (j < n && s[j] === s[i]) { + j++; + } + const k = s[i].charCodeAt(0) - 'a'.charCodeAt(0); + cnt[k] += Math.max(0, j - i - x + 1); + if (cnt[k] >= 3) { + return true; + } + i = j; + } + return false; + }; + while (l < r) { + const mid = (l + r + 1) >> 1; + if (check(mid)) { + l = mid; + } else { + r = mid - 1; + } + } + return l === 0 ? -1 : l; +} diff --git a/solution/2900-2999/2982.Find Longest Special Substring That Occurs Thrice II/README.md b/solution/2900-2999/2982.Find Longest Special Substring That Occurs Thrice II/README.md index 0ad00c8416169..7dbc5017fdcc0 100644 --- a/solution/2900-2999/2982.Find Longest Special Substring That Occurs Thrice II/README.md +++ b/solution/2900-2999/2982.Find Longest Special Substring That Occurs Thrice II/README.md @@ -55,6 +55,20 @@ +**方法一:二分查找 + 滑动窗口计数** + +我们注意到,如果一个长度为 $x$ 且出现至少三次的特殊子字符串存在,那么长度为 $x-1$ 的特殊子字符串也一定存在,这存在着单调性,因此我们可以使用二分查找的方法来找到最长的特殊子字符串。 + +我们定义二分查找的左边界 $l = 0$,右边界 $r = n$,其中 $n$ 是字符串的长度。每次二分查找的过程中,我们取 $mid = \lfloor \frac{l + r + 1}{2} \rfloor$,如果长度为 $mid$ 的特殊子字符串存在,那么我们就将左边界更新为 $mid$,否则我们就将右边界更新为 $mid - 1$。在二分查找的过程中,我们使用滑动窗口来计算特殊子字符串的个数。 + +具体地,我们设计一个函数 $check(x)$,表示长度为 $x$ 且出现至少三次的特殊子字符串是否存在。 + +在函数 $check(x)$ 中,我们定义一个哈希表或长度为 $26$ 的数组 $cnt$,其中 $cnt[i]$ 表示长度为 $x$,且由第 $i$ 个小写字母组成的特殊子字符串的个数。我们遍历字符串 $s$,如果当前遍历到的字符为 $s[i]$,那么我们将指针 $j$ 向右移动,直到 $s[j] \neq s[i]$,此时 $s[i \cdots j-1]$ 就是一个长度为 $x$ 的特殊子字符串,我们将 $cnt[s[i]]$ 增加 $\max(0, j - i - x + 1)$,然后将指针 $i$ 更新为 $j$。 + +在遍历结束之后,我们遍历数组 $cnt$,如果存在 $cnt[i] \geq 3$,那么就说明长度为 $x$ 且出现至少三次的特殊子字符串存在,我们返回 $true$,否则返回 $false$。 + +时间复杂度 $O((n + |\Sigma|) \times \log n)$,空间复杂度 $O(|\Sigma|)$,其中 $n$ 是字符串 $s$ 的长度,而 $|\Sigma|$ 表示字符集的大小,本题中字符集为小写英文字母,因此 $|\Sigma| = 26$。 + ### **Python3** @@ -62,7 +76,28 @@ ```python - +class Solution: + def maximumLength(self, s: str) -> int: + def check(x: int) -> bool: + cnt = defaultdict(int) + i = 0 + while i < n: + j = i + 1 + while j < n and s[j] == s[i]: + j += 1 + cnt[s[i]] += max(0, j - i - x + 1) + i = j + return max(cnt.values()) >= 3 + + n = len(s) + l, r = 0, n + while l < r: + mid = (l + r + 1) >> 1 + if check(mid): + l = mid + else: + r = mid - 1 + return -1 if l == 0 else l ``` ### **Java** @@ -70,19 +105,150 @@ ```java - +class Solution { + private String s; + private int n; + + public int maximumLength(String s) { + this.s = s; + n = s.length(); + int l = 0, r = n; + while (l < r) { + int mid = (l + r + 1) >> 1; + if (check(mid)) { + l = mid; + } else { + r = mid - 1; + } + } + return l == 0 ? -1 : l; + } + + private boolean check(int x) { + int[] cnt = new int[26]; + for (int i = 0; i < n;) { + int j = i + 1; + while (j < n && s.charAt(j) == s.charAt(i)) { + j++; + } + int k = s.charAt(i) - 'a'; + cnt[k] += Math.max(0, j - i - x + 1); + if (cnt[k] >= 3) { + return true; + } + i = j; + } + return false; + } +} ``` ### **C++** ```cpp - +class Solution { +public: + int maximumLength(string s) { + int n = s.size(); + int l = 0, r = n; + auto check = [&](int x) { + int cnt[26]{}; + for (int i = 0; i < n;) { + int j = i + 1; + while (j < n && s[j] == s[i]) { + ++j; + } + int k = s[i] - 'a'; + cnt[k] += max(0, j - i - x + 1); + if (cnt[k] >= 3) { + return true; + } + i = j; + } + return false; + }; + while (l < r) { + int mid = (l + r + 1) >> 1; + if (check(mid)) { + l = mid; + } else { + r = mid - 1; + } + } + return l == 0 ? -1 : l; + } +}; ``` ### **Go** ```go +func maximumLength(s string) int { + n := len(s) + l, r := 0, n + check := func(x int) bool { + cnt := [26]int{} + for i := 0; i < n; { + j := i + 1 + for j < n && s[j] == s[i] { + j++ + } + k := s[i] - 'a' + cnt[k] += max(0, j-i-x+1) + if cnt[k] >= 3 { + return true + } + i = j + } + return false + } + for l < r { + mid := (l + r + 1) >> 1 + if check(mid) { + l = mid + } else { + r = mid - 1 + } + } + if l == 0 { + return -1 + } + return l +} +``` +### **TypeScript** + +```ts +function maximumLength(s: string): number { + const n = s.length; + let [l, r] = [0, n]; + const check = (x: number): boolean => { + const cnt: number[] = Array(26).fill(0); + for (let i = 0; i < n; ) { + let j = i + 1; + while (j < n && s[j] === s[i]) { + j++; + } + const k = s[i].charCodeAt(0) - 'a'.charCodeAt(0); + cnt[k] += Math.max(0, j - i - x + 1); + if (cnt[k] >= 3) { + return true; + } + i = j; + } + return false; + }; + while (l < r) { + const mid = (l + r + 1) >> 1; + if (check(mid)) { + l = mid; + } else { + r = mid - 1; + } + } + return l === 0 ? -1 : l; +} ``` ### **...** diff --git a/solution/2900-2999/2982.Find Longest Special Substring That Occurs Thrice II/README_EN.md b/solution/2900-2999/2982.Find Longest Special Substring That Occurs Thrice II/README_EN.md index b0007f54bd684..f421c8b4c8486 100644 --- a/solution/2900-2999/2982.Find Longest Special Substring That Occurs Thrice II/README_EN.md +++ b/solution/2900-2999/2982.Find Longest Special Substring That Occurs Thrice II/README_EN.md @@ -49,30 +49,196 @@ It can be shown that the maximum length achievable is 1. ## Solutions +**Solution 1: Binary Search + Sliding Window Counting** + +We notice that if there exists a special substring of length $x$ that appears at least three times, then a special substring of length $x-1$ must also exist. This exhibits a monotonicity, so we can use binary search to find the longest special substring. + +We define the left boundary of the binary search as $l = 0$ and the right boundary as $r = n$, where $n$ is the length of the string. In each binary search, we take $mid = \lfloor \frac{l + r + 1}{2} \rfloor$. If a special substring of length $mid$ exists, we update the left boundary to $mid$. Otherwise, we update the right boundary to $mid - 1$. During the binary search, we use a sliding window to count the number of special substrings. + +Specifically, we design a function $check(x)$ to indicate whether a special substring of length $x$ that appears at least three times exists. + +In the function $check(x)$, we define a hash table or an array of length $26$ named $cnt$, where $cnt[i]$ represents the count of special substrings of length $x$ composed of the $i$-th lowercase letter. We traverse the string $s$. If the current character is $s[i]$, we move the pointer $j$ to the right until $s[j] \neq s[i]$. At this point, $s[i \cdots j-1]$ is a special substring of length $x$. We increase $cnt[s[i]]$ by $\max(0, j - i - x + 1)$, and then update the pointer $i$ to $j$. + +After the traversal, we go through the array $cnt$. If there exists $cnt[i] \geq 3$, it means a special substring of length $x$ that appears at least three times exists, so we return $true$. Otherwise, we return $false$. + +The time complexity is $O((n + |\Sigma|) \times \log n)$, and the space complexity is $O(|\Sigma|)$, where $n$ is the length of the string $s$, and $|\Sigma|$ represents the size of the character set. In this problem, the character set is lowercase English letters, so $|\Sigma| = 26$. + ### **Python3** ```python - +class Solution: + def maximumLength(self, s: str) -> int: + def check(x: int) -> bool: + cnt = defaultdict(int) + i = 0 + while i < n: + j = i + 1 + while j < n and s[j] == s[i]: + j += 1 + cnt[s[i]] += max(0, j - i - x + 1) + i = j + return max(cnt.values()) >= 3 + + n = len(s) + l, r = 0, n + while l < r: + mid = (l + r + 1) >> 1 + if check(mid): + l = mid + else: + r = mid - 1 + return -1 if l == 0 else l ``` ### **Java** ```java - +class Solution { + private String s; + private int n; + + public int maximumLength(String s) { + this.s = s; + n = s.length(); + int l = 0, r = n; + while (l < r) { + int mid = (l + r + 1) >> 1; + if (check(mid)) { + l = mid; + } else { + r = mid - 1; + } + } + return l == 0 ? -1 : l; + } + + private boolean check(int x) { + int[] cnt = new int[26]; + for (int i = 0; i < n;) { + int j = i + 1; + while (j < n && s.charAt(j) == s.charAt(i)) { + j++; + } + int k = s.charAt(i) - 'a'; + cnt[k] += Math.max(0, j - i - x + 1); + if (cnt[k] >= 3) { + return true; + } + i = j; + } + return false; + } +} ``` ### **C++** ```cpp - +class Solution { +public: + int maximumLength(string s) { + int n = s.size(); + int l = 0, r = n; + auto check = [&](int x) { + int cnt[26]{}; + for (int i = 0; i < n;) { + int j = i + 1; + while (j < n && s[j] == s[i]) { + ++j; + } + int k = s[i] - 'a'; + cnt[k] += max(0, j - i - x + 1); + if (cnt[k] >= 3) { + return true; + } + i = j; + } + return false; + }; + while (l < r) { + int mid = (l + r + 1) >> 1; + if (check(mid)) { + l = mid; + } else { + r = mid - 1; + } + } + return l == 0 ? -1 : l; + } +}; ``` ### **Go** ```go +func maximumLength(s string) int { + n := len(s) + l, r := 0, n + check := func(x int) bool { + cnt := [26]int{} + for i := 0; i < n; { + j := i + 1 + for j < n && s[j] == s[i] { + j++ + } + k := s[i] - 'a' + cnt[k] += max(0, j-i-x+1) + if cnt[k] >= 3 { + return true + } + i = j + } + return false + } + for l < r { + mid := (l + r + 1) >> 1 + if check(mid) { + l = mid + } else { + r = mid - 1 + } + } + if l == 0 { + return -1 + } + return l +} +``` +### **TypeScript** + +```ts +function maximumLength(s: string): number { + const n = s.length; + let [l, r] = [0, n]; + const check = (x: number): boolean => { + const cnt: number[] = Array(26).fill(0); + for (let i = 0; i < n; ) { + let j = i + 1; + while (j < n && s[j] === s[i]) { + j++; + } + const k = s[i].charCodeAt(0) - 'a'.charCodeAt(0); + cnt[k] += Math.max(0, j - i - x + 1); + if (cnt[k] >= 3) { + return true; + } + i = j; + } + return false; + }; + while (l < r) { + const mid = (l + r + 1) >> 1; + if (check(mid)) { + l = mid; + } else { + r = mid - 1; + } + } + return l === 0 ? -1 : l; +} ``` ### **...** diff --git a/solution/2900-2999/2982.Find Longest Special Substring That Occurs Thrice II/Solution.cpp b/solution/2900-2999/2982.Find Longest Special Substring That Occurs Thrice II/Solution.cpp new file mode 100644 index 0000000000000..cc67a747769d8 --- /dev/null +++ b/solution/2900-2999/2982.Find Longest Special Substring That Occurs Thrice II/Solution.cpp @@ -0,0 +1,32 @@ +class Solution { +public: + int maximumLength(string s) { + int n = s.size(); + int l = 0, r = n; + auto check = [&](int x) { + int cnt[26]{}; + for (int i = 0; i < n;) { + int j = i + 1; + while (j < n && s[j] == s[i]) { + ++j; + } + int k = s[i] - 'a'; + cnt[k] += max(0, j - i - x + 1); + if (cnt[k] >= 3) { + return true; + } + i = j; + } + return false; + }; + while (l < r) { + int mid = (l + r + 1) >> 1; + if (check(mid)) { + l = mid; + } else { + r = mid - 1; + } + } + return l == 0 ? -1 : l; + } +}; \ No newline at end of file diff --git a/solution/2900-2999/2982.Find Longest Special Substring That Occurs Thrice II/Solution.go b/solution/2900-2999/2982.Find Longest Special Substring That Occurs Thrice II/Solution.go new file mode 100644 index 0000000000000..94a47b6b03c98 --- /dev/null +++ b/solution/2900-2999/2982.Find Longest Special Substring That Occurs Thrice II/Solution.go @@ -0,0 +1,32 @@ +func maximumLength(s string) int { + n := len(s) + l, r := 0, n + check := func(x int) bool { + cnt := [26]int{} + for i := 0; i < n; { + j := i + 1 + for j < n && s[j] == s[i] { + j++ + } + k := s[i] - 'a' + cnt[k] += max(0, j-i-x+1) + if cnt[k] >= 3 { + return true + } + i = j + } + return false + } + for l < r { + mid := (l + r + 1) >> 1 + if check(mid) { + l = mid + } else { + r = mid - 1 + } + } + if l == 0 { + return -1 + } + return l +} \ No newline at end of file diff --git a/solution/2900-2999/2982.Find Longest Special Substring That Occurs Thrice II/Solution.java b/solution/2900-2999/2982.Find Longest Special Substring That Occurs Thrice II/Solution.java new file mode 100644 index 0000000000000..25f93a56fea62 --- /dev/null +++ b/solution/2900-2999/2982.Find Longest Special Substring That Occurs Thrice II/Solution.java @@ -0,0 +1,36 @@ +class Solution { + private String s; + private int n; + + public int maximumLength(String s) { + this.s = s; + n = s.length(); + int l = 0, r = n; + while (l < r) { + int mid = (l + r + 1) >> 1; + if (check(mid)) { + l = mid; + } else { + r = mid - 1; + } + } + return l == 0 ? -1 : l; + } + + private boolean check(int x) { + int[] cnt = new int[26]; + for (int i = 0; i < n;) { + int j = i + 1; + while (j < n && s.charAt(j) == s.charAt(i)) { + j++; + } + int k = s.charAt(i) - 'a'; + cnt[k] += Math.max(0, j - i - x + 1); + if (cnt[k] >= 3) { + return true; + } + i = j; + } + return false; + } +} \ No newline at end of file diff --git a/solution/2900-2999/2982.Find Longest Special Substring That Occurs Thrice II/Solution.py b/solution/2900-2999/2982.Find Longest Special Substring That Occurs Thrice II/Solution.py new file mode 100644 index 0000000000000..ce1b4f5856c5e --- /dev/null +++ b/solution/2900-2999/2982.Find Longest Special Substring That Occurs Thrice II/Solution.py @@ -0,0 +1,22 @@ +class Solution: + def maximumLength(self, s: str) -> int: + def check(x: int) -> bool: + cnt = defaultdict(int) + i = 0 + while i < n: + j = i + 1 + while j < n and s[j] == s[i]: + j += 1 + cnt[s[i]] += max(0, j - i - x + 1) + i = j + return max(cnt.values()) >= 3 + + n = len(s) + l, r = 0, n + while l < r: + mid = (l + r + 1) >> 1 + if check(mid): + l = mid + else: + r = mid - 1 + return -1 if l == 0 else l diff --git a/solution/2900-2999/2982.Find Longest Special Substring That Occurs Thrice II/Solution.ts b/solution/2900-2999/2982.Find Longest Special Substring That Occurs Thrice II/Solution.ts new file mode 100644 index 0000000000000..fdb8cab521ead --- /dev/null +++ b/solution/2900-2999/2982.Find Longest Special Substring That Occurs Thrice II/Solution.ts @@ -0,0 +1,29 @@ +function maximumLength(s: string): number { + const n = s.length; + let [l, r] = [0, n]; + const check = (x: number): boolean => { + const cnt: number[] = Array(26).fill(0); + for (let i = 0; i < n; ) { + let j = i + 1; + while (j < n && s[j] === s[i]) { + j++; + } + const k = s[i].charCodeAt(0) - 'a'.charCodeAt(0); + cnt[k] += Math.max(0, j - i - x + 1); + if (cnt[k] >= 3) { + return true; + } + i = j; + } + return false; + }; + while (l < r) { + const mid = (l + r + 1) >> 1; + if (check(mid)) { + l = mid; + } else { + r = mid - 1; + } + } + return l === 0 ? -1 : l; +}