Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Index/二分.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
| [1707. 与数组中元素的最大异或值](https://leetcode-cn.com/problems/maximum-xor-with-an-element-from-array/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/maximum-xor-with-an-element-from-array/solution/gong-shui-san-xie-jie-zhe-ge-wen-ti-lai-lypqr/) | 困难 | 🤩🤩🤩 |
| [1713. 得到子序列的最少操作次数](https://leetcode-cn.com/problems/minimum-operations-to-make-a-subsequence/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/minimum-operations-to-make-a-subsequence/solution/gong-shui-san-xie-noxiang-xin-ke-xue-xi-oj7yu/) | 困难 | 🤩🤩🤩 |
| [1751. 最多可以参加的会议数目 II](https://leetcode-cn.com/problems/maximum-number-of-events-that-can-be-attended-ii/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/maximum-number-of-events-that-can-be-attended-ii/solution/po-su-dp-er-fen-dp-jie-fa-by-ac_oier-88du/) | 困难 | 🤩🤩🤩 |
| [1760. 袋子里最少数目的球](https://leetcode.cn/problems/minimum-limit-of-balls-in-a-bag/) | [LeetCode 题解链接](https://acoier.com/2022/12/23/1760.%20%E8%A2%8B%E5%AD%90%E9%87%8C%E6%9C%80%E5%B0%91%E6%95%B0%E7%9B%AE%E7%9A%84%E7%90%83%EF%BC%88%E4%B8%AD%E7%AD%89%EF%BC%89/) | 中等 | 🤩🤩🤩🤩🤩 |
| [1818. 绝对差值和](https://leetcode-cn.com/problems/minimum-absolute-sum-difference/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/minimum-absolute-sum-difference/solution/gong-shui-san-xie-tong-guo-er-fen-zhao-z-vrmq/) | 中等 | 🤩🤩🤩🤩🤩 |
| [1838. 最高频元素的频数](https://leetcode-cn.com/problems/frequency-of-the-most-frequent-element/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/frequency-of-the-most-frequent-element/solution/gong-shui-san-xie-cong-mei-ju-dao-pai-xu-kxnk/) | 中等 | 🤩🤩🤩 |
| [1894. 找到需要补充粉笔的学生编号](https://leetcode-cn.com/problems/find-the-student-that-will-replace-the-chalk/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/find-the-student-that-will-replace-the-chalk/solution/gong-shui-san-xie-yi-ti-shuang-jie-qian-kpqsk/) | 中等 | 🤩🤩🤩🤩 |
Expand Down
1 change: 1 addition & 0 deletions Index/双指针.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
| [1697. 检查边长度限制的路径是否存在](https://leetcode.cn/problems/checking-existence-of-edge-length-limited-paths/) | [LeetCode 题解链接](https://acoier.com/2022/12/14/1697.%20%E6%A3%80%E6%9F%A5%E8%BE%B9%E9%95%BF%E5%BA%A6%E9%99%90%E5%88%B6%E7%9A%84%E8%B7%AF%E5%BE%84%E6%98%AF%E5%90%A6%E5%AD%98%E5%9C%A8%EF%BC%88%E5%9B%B0%E9%9A%BE%EF%BC%89/) | 困难 | 🤩🤩🤩🤩 |
| [1743. 从相邻元素对还原数组](https://leetcode-cn.com/problems/restore-the-array-from-adjacent-pairs/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/restore-the-array-from-adjacent-pairs/solution/gong-shui-san-xie-yi-ti-shuang-jie-dan-x-elpx/) | 中等 | 🤩🤩🤩🤩 |
| [1748. 唯一元素的和](https://leetcode-cn.com/problems/sum-of-unique-elements/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/sum-of-unique-elements/solution/gong-shui-san-xie-yi-ti-shuang-jie-pai-x-atnd/) | 简单 | 🤩🤩🤩🤩 |
| [1759. 统计同构子字符串的数目](https://leetcode.cn/problems/count-number-of-homogenous-substrings/) | [LeetCode 题解链接](https://acoier.com/2022/12/26/1759.%20%E7%BB%9F%E8%AE%A1%E5%90%8C%E6%9E%84%E5%AD%90%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E6%95%B0%E7%9B%AE%EF%BC%88%E4%B8%AD%E7%AD%89%EF%BC%89/) | 中等 | 🤩🤩🤩🤩 |
| [1764. 通过连接另一个数组的子数组得到一个数组](https://leetcode-cn.com/problems/form-array-by-concatenating-subarrays-of-another-array/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/form-array-by-concatenating-subarrays-of-another-array/solution/clean-solutionni-jue-dui-neng-kan-dong-d-l4ts/) | 中等 | 🤩🤩🤩🤩 |
| [2000. 反转单词前缀](https://leetcode-cn.com/problems/reverse-prefix-of-word/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/reverse-prefix-of-word/solution/gong-shui-san-xie-jian-dan-shuang-zhi-zh-dp9u/) | 简单 | 🤩🤩🤩🤩 |
| [2024. 考试的最大困扰度](https://leetcode-cn.com/problems/maximize-the-confusion-of-an-exam/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/maximize-the-confusion-of-an-exam/solution/by-ac_oier-2rii/) | 中等 | 🤩🤩🤩🤩 |
Expand Down
1 change: 1 addition & 0 deletions Index/数学.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
| [1720. 解码异或后的数组](https://leetcode-cn.com/problems/decode-xored-array/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/decode-xored-array/solution/gong-shui-san-xie-li-yong-yi-huo-xing-zh-p1bi/) | 简单 | 🤩🤩🤩 |
| [1734. 解码异或后的排列](https://leetcode-cn.com/problems/decode-xored-permutation/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/decode-xored-permutation/solution/gong-shui-san-xie-note-bie-pian-li-yong-zeh6o/) | 中等 | 🤩🤩🤩🤩 |
| [1738. 找出第 K 大的异或坐标值](https://leetcode-cn.com/problems/find-kth-largest-xor-coordinate-value/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/find-kth-largest-xor-coordinate-value/solution/gong-shui-san-xie-xiang-jie-li-yong-er-w-ai0d/) | 中等 | 🤩🤩🤩 |
| [1759. 统计同构子字符串的数目](https://leetcode.cn/problems/count-number-of-homogenous-substrings/) | [LeetCode 题解链接](https://acoier.com/2022/12/26/1759.%20%E7%BB%9F%E8%AE%A1%E5%90%8C%E6%9E%84%E5%AD%90%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E6%95%B0%E7%9B%AE%EF%BC%88%E4%B8%AD%E7%AD%89%EF%BC%89/) | 中等 | 🤩🤩🤩🤩 |
| [1775. 通过最少操作次数使数组的和相等](https://leetcode.cn/problems/equal-sum-arrays-with-minimum-number-of-operations/) | [LeetCode 题解链接](https://acoier.com/2022/12/09/1775.%20%E9%80%9A%E8%BF%87%E6%9C%80%E5%B0%91%E6%93%8D%E4%BD%9C%E6%AC%A1%E6%95%B0%E4%BD%BF%E6%95%B0%E7%BB%84%E7%9A%84%E5%92%8C%E7%9B%B8%E7%AD%89%EF%BC%88%E4%B8%AD%E7%AD%89%EF%BC%89/) | 中等 | 🤩🤩🤩🤩 |
| [1780. 判断一个数字是否可以表示成三的幂的和](https://leetcode.cn/problems/check-if-number-is-a-sum-of-powers-of-three/) | [LeetCode 题解链接](https://acoier.com/2022/12/12/1780.%20%E5%88%A4%E6%96%AD%E4%B8%80%E4%B8%AA%E6%95%B0%E5%AD%97%E6%98%AF%E5%90%A6%E5%8F%AF%E4%BB%A5%E8%A1%A8%E7%A4%BA%E6%88%90%E4%B8%89%E7%9A%84%E5%B9%82%E7%9A%84%E5%92%8C%EF%BC%88%E4%B8%AD%E7%AD%89%EF%BC%89/) | 中等 | 🤩🤩🤩🤩🤩 |
| [剑指 Offer 44. 数字序列中某一位的数字](https://leetcode.cn/problems/shu-zi-xu-lie-zhong-mou-yi-wei-de-shu-zi-lcof/) | [LeetCode 题解链接](https://leetcode.cn/problems/shu-zi-xu-lie-zhong-mou-yi-wei-de-shu-zi-lcof/solution/by-ac_oier-wgr8/) | 中等 | 🤩🤩🤩🤩 |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
### 题目描述

这是 LeetCode 上的 **[1759. 统计同构子字符串的数目](https://acoier.com/2022/12/26/1759.%20%E7%BB%9F%E8%AE%A1%E5%90%8C%E6%9E%84%E5%AD%90%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E6%95%B0%E7%9B%AE%EF%BC%88%E4%B8%AD%E7%AD%89%EF%BC%89/)** ,难度为 **中等**。

Tag : 「双指针」、「数学」



给你一个字符串 `s`,返回 `s` 中 同构子字符串 的数目。由于答案可能很大,只需返回对 $10^9 + 7$ 取余 后的结果。

同构字符串 的定义为:如果一个字符串中的所有字符都相同,那么该字符串就是同构字符串。

子字符串 是字符串中的一个连续字符序列。

示例 1:
```
输入:s = "abbcccaa"

输出:13

解释:同构子字符串如下所列:
"a" 出现 3 次。
"aa" 出现 1 次。
"b" 出现 2 次。
"bb" 出现 1 次。
"c" 出现 3 次。
"cc" 出现 2 次。
"ccc" 出现 1 次。
3 + 1 + 2 + 1 + 3 + 2 + 1 = 13
```
示例 2:
```
输入:s = "xy"

输出:2

解释:同构子字符串是 "x" 和 "y" 。
```
示例 3:
```
输入:s = "zzzzz"

输出:15
```

提示:
* $1 <= s.length <= 10^5$
* `s` 由小写字符串组成


---

### 双指针 + 数学

根据题意,我们需要找出 `s` 中所有字符相同的连续段。

假设 $s[i...(j - 1)]$ 为某个连续段,长度为 $m$,根据「等差数列求和」可知该连续段所能提供的同构字符串数量为 $\frac{(1 + m) \times m}{2}$。

具体的,我们可以从前往后扫描 `s`,假设当前处理到的位置为 `i`,将其看作连续段的左端点,然后从 `i` 出发找到当前最长连续段的右端点 `j - 1`,统计 $s[i...(j - 1)]$ 所能贡献同构字符串数量,并调整下个发起点为 $i = j$ 以扫描下一个连续段。

Java 代码:
```Java
class Solution {
public int countHomogenous(String s) {
int n = s.length(), MOD = (int)1e9+7;
long ans = 0;
for (int i = 0; i < n; ) {
int j = i;
while (j < n && s.charAt(j) == s.charAt(i)) j++;
long cnt = j - i;
ans += (1 + cnt) * cnt / 2;
ans %= MOD;
i = j;
}
return (int) ans;
}
}
```
TypeScript 代码:
```TypeScript
function countHomogenous(s: string): number {
let n = s.length, mod = 1e9+7, ans = 0
for (let i = 0; i < n; ) {
let j = i
while (j < n && s.charAt(j) == s.charAt(i)) j++
const cnt = j - i
ans += (1 + cnt) * cnt / 2
ans %= mod
i = j
}
return ans
}
```
Python3 代码:
```Python3
class Solution:
def countHomogenous(self, s: str) -> int:
n, mod, i, ans = len(s), 1e9+7, 0, 0
while i < n:
j = i
while j < n and s[j] == s[i]:
j += 1
cnt = j - i
ans += (cnt + 1) * cnt / 2
ans %= mod
i = j
return int(ans)
```
* 时间复杂度:$O(n)$
* 空间复杂度:$O(1)$

---

### 最后

这是我们「刷穿 LeetCode」系列文章的第 `No.1759` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。

在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。

为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode 。

在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。

140 changes: 140 additions & 0 deletions LeetCode/1751-1760/1760. 袋子里最少数目的球(中等).md
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
### 题目描述

这是 LeetCode 上的 **[1760. 袋子里最少数目的球](https://acoier.com/2022/12/23/1760.%20%E8%A2%8B%E5%AD%90%E9%87%8C%E6%9C%80%E5%B0%91%E6%95%B0%E7%9B%AE%E7%9A%84%E7%90%83%EF%BC%88%E4%B8%AD%E7%AD%89%EF%BC%89/)** ,难度为 **中等**。

Tag : 「二分」



给你一个整数数组 `nums`,其中 `nums[i]` 表示第 `i` 个袋子里球的数目。同时给你一个整数 `maxOperations`。

你可以进行如下操作至多 `maxOperations` 次:

* 选择任意一个袋子,并将袋子里的球分到 `2` 个新的袋子中,每个袋子里都有 正整数 个球。
* 比方说,一个袋子里有 `5` 个球,你可以把它们分到两个新袋子里,分别有 `1` 个和 `4` 个球,或者分别有 `2` 个和 `3` 个球。
你的开销是单个袋子里球数目的 最大值 ,你想要 最小化 开销。

请你返回进行上述操作后的最小开销。

示例 1:
```
输入:nums = [9], maxOperations = 2

输出:3

解释:
- 将装有 9 个球的袋子分成装有 6 个和 3 个球的袋子。[9] -> [6,3] 。
- 将装有 6 个球的袋子分成装有 3 个和 3 个球的袋子。[6,3] -> [3,3,3] 。
装有最多球的袋子里装有 3 个球,所以开销为 3 并返回 3 。
```
示例 2:
```
输入:nums = [2,4,8,2], maxOperations = 4

输出:2

解释:
- 将装有 8 个球的袋子分成装有 4 个和 4 个球的袋子。[2,4,8,2] -> [2,4,4,4,2] 。
- 将装有 4 个球的袋子分成装有 2 个和 2 个球的袋子。[2,4,4,4,2] -> [2,2,2,4,4,2] 。
- 将装有 4 个球的袋子分成装有 2 个和 2 个球的袋子。[2,2,2,4,4,2] -> [2,2,2,2,2,4,2] 。
- 将装有 4 个球的袋子分成装有 2 个和 2 个球的袋子。[2,2,2,2,2,4,2] -> [2,2,2,2,2,2,2,2] 。
装有最多球的袋子里装有 2 个球,所以开销为 2 并返回 2 。
```
示例 3:
```
输入:nums = [7,17], maxOperations = 2

输出:7
```

提示:
* $1 <= nums.length <= 10^5$
* $1 <= maxOperations, nums[i] <= 10^9$

---

### 二分

最小化不超过 `max` 次划分操作后的单个袋子最大值,我们将其称为「划分值」。

**答案具有二段性:若使用 $k \leq \max$ 次划分操作后可达到最小划分值,此时减少划分操作次数,会使得划分值非单调上升。**

因此我们可以二分答案,从而将问题进行等价转换:

**假设当前二分到的值为 $limit$,我们需要实现一个线性复杂度为 `check` 函数,判断能否使用不超过 $\max$ 次划分次数,来使得划分值不超过 $limit$**:

* 若能满足,说明 $[limit, +\infty]$ 范围的划分值,均能使用不超过 $\max$ 次的实现,此时让 $r = limit$
* 若不能满足,比 $limit$ 更小的划分值,则更无法在 $\max$ 次操作中满足,说明 $[1, limit]$ 范围划分值均不是答案,此时让 $l = limit + 1$

考虑如何实现 `check` 函数,从前往后处理每个 $nums[i]$,根据 $nums[i]$ 与当前限制 $limit$ 的大小关系进行分情况讨论:

* 若 $nums[i] \leq limit$:说明当前袋子不会成为瓶颈,无须消耗划分次数
* 若 $nums[i] > limit$:此时需要对当前袋子进行划分,直到满足单个袋子球的数量不超过 $limit$ 为止,由于每次划分相当于增加一个袋子,而将 $nums[i]$ 划分成若干个不超过 $limit$ 个球的袋子,需要 $\left \lceil \frac{nums[i]}{limit} \right \rceil$ 个袋子,减去原本的一个,共需要增加 $\left \lceil \frac{nums[i]}{limit} \right \rceil$ 个新袋子,即划分 $\left \lceil \frac{nums[i]}{limit} \right \rceil$ 次


Java 代码:
```Java
class Solution {
public int minimumSize(int[] nums, int max) {
int l = 1, r = 0x3f3f3f3f;
while (l < r) {
int mid = l + r >> 1;
if (check(nums, mid, max)) r = mid;
else l = mid + 1;
}
return r;
}
boolean check(int[] nums, int limit, int max) {
int cnt = 0;
for (int x : nums) cnt += Math.ceil(x * 1.0 / limit) - 1;
return cnt <= max;
}
}
```
TypeScript 代码:
```TypeScript
function minimumSize(nums: number[], max: number): number {
function check(nums: number[], limit: number, max: number): boolean {
let cnt = 0
for (const x of nums) cnt += Math.ceil(x / limit) - 1
return cnt <= max
}
let l = 1, r = 0x3f3f3f3f
while (l < r) {
const mid = l + r >> 1
if (check(nums, mid, max)) r = mid
else l = mid + 1
}
return r
}
```
Python 代码:
```Python
class Solution:
def minimumSize(self, nums: List[int], maxv: int) -> int:
def check(nums, limit, maxv):
return sum([(x + limit - 1) // limit - 1 for x in nums]) <= maxv
l, r = 1, 0x3f3f3f3f
while l < r:
mid = l + r >> 1
if check(nums, mid, maxv):
r = mid
else:
l = mid + 1
return r
```
* 时间复杂度:$O(n \log{M})$,其中 $M = 1e9$ 为值域大小
* 空间复杂度:$O(1)$

---

### 最后

这是我们「刷穿 LeetCode」系列文章的第 `No.1758` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。

在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。

为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode 。

在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。

Loading