Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 07db44c

Browse files
author
robot
committed
feat: 2842,ドル 2866ドル
1 parent cb52959 commit 07db44c

File tree

2 files changed

+234
-0
lines changed

2 files changed

+234
-0
lines changed
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
## 题目地址(2842. 统计一个字符串的 k 子序列美丽值最大的数目)
2+
3+
https://leetcode.cn/problems/count-k-subsequences-of-a-string-with-maximum-beauty/
4+
5+
## 题目描述
6+
7+
```
8+
给你一个字符串 s 和一个整数 k 。
9+
10+
k 子序列指的是 s 的一个长度为 k 的 子序列 ,且所有字符都是 唯一 的,也就是说每个字符在子序列里只出现过一次。
11+
12+
定义 f(c) 为字符 c 在 s 中出现的次数。
13+
14+
k 子序列的 美丽值 定义为这个子序列中每一个字符 c 的 f(c) 之 和 。
15+
16+
比方说,s = "abbbdd" 和 k = 2 ,我们有:
17+
18+
f('a') = 1, f('b') = 3, f('d') = 2
19+
s 的部分 k 子序列为:
20+
"abbbdd" -> "ab" ,美丽值为 f('a') + f('b') = 4
21+
"abbbdd" -> "ad" ,美丽值为 f('a') + f('d') = 3
22+
"abbbdd" -> "bd" ,美丽值为 f('b') + f('d') = 5
23+
请你返回一个整数,表示所有 k 子序列 里面 美丽值 是 最大值 的子序列数目。由于答案可能很大,将结果对 109 + 7 取余后返回。
24+
25+
一个字符串的子序列指的是从原字符串里面删除一些字符(也可能一个字符也不删除),不改变剩下字符顺序连接得到的新字符串。
26+
27+
注意:
28+
29+
f(c) 指的是字符 c 在字符串 s 的出现次数,不是在 k 子序列里的出现次数。
30+
两个 k 子序列如果有任何一个字符在原字符串中的下标不同,则它们是两个不同的子序列。所以两个不同的 k 子序列可能产生相同的字符串。
31+
32+
33+
示例 1:
34+
35+
输入:s = "bcca", k = 2
36+
输出:4
37+
解释:s 中我们有 f('a') = 1 ,f('b') = 1 和 f('c') = 2 。
38+
s 的 k 子序列为:
39+
bcca ,美丽值为 f('b') + f('c') = 3
40+
bcca ,美丽值为 f('b') + f('c') = 3
41+
bcca ,美丽值为 f('b') + f('a') = 2
42+
bcca ,美丽值为 f('c') + f('a') = 3
43+
bcca ,美丽值为 f('c') + f('a') = 3
44+
总共有 4 个 k 子序列美丽值为最大值 3 。
45+
所以答案为 4 。
46+
示例 2:
47+
48+
输入:s = "abbcd", k = 4
49+
输出:2
50+
解释:s 中我们有 f('a') = 1 ,f('b') = 2 ,f('c') = 1 和 f('d') = 1 。
51+
s 的 k 子序列为:
52+
abbcd ,美丽值为 f('a') + f('b') + f('c') + f('d') = 5
53+
abbcd ,美丽值为 f('a') + f('b') + f('c') + f('d') = 5
54+
总共有 2 个 k 子序列美丽值为最大值 5 。
55+
所以答案为 2 。
56+
57+
58+
提示:
59+
60+
1 <= s.length <= 2 * 105
61+
1 <= k <= s.length
62+
s 只包含小写英文字母。
63+
```
64+
65+
## 前置知识
66+
67+
- 排列组合
68+
69+
## 思路
70+
71+
显然我们应该贪心地使用频率高的,也就是 f(c) 大的 c。
72+
73+
因此一个思路就是从大到小选择 c,由于同一个 c 是不同的方案。因此选择 c 就有 f(c) 种选法。
74+
75+
如果有两个相同频率的,那么方案数就是 f(c) * f(c)。 如果有 k 个频率相同的,方案数就是 f(c) ** k。
76+
77+
如果有 num 个频率相同的要选,但是只能选 k 个,k < num。那么就可以从 num 个先选 k 个,方案数是 C_{num}^{k},然后再用上面的计算方法计算。
78+
79+
最后利用乘法原理,将依次选择的方案数乘起来就好了。
80+
81+
## 代码
82+
83+
- 语言支持:Python3
84+
85+
Python3 Code:
86+
87+
```python
88+
class Solution:
89+
def countKSubsequencesWithMaxBeauty(self, s: str, k: int) -> int:
90+
MOD = 10 ** 9 + 7
91+
ans = 1
92+
cnt = Counter(Counter(s).values())
93+
for c, num in sorted(cnt.items(), reverse=True):
94+
# c 是出现次数
95+
# num 是出现次数为 c 的有多少个
96+
if num >= k:
97+
return ans * pow(c, k, MOD) * comb(num, k) % MOD
98+
ans *= pow(c, num, MOD) * comb(num, num) % MOD
99+
k -= num
100+
return 0
101+
102+
```
103+
104+
105+
**复杂度分析**
106+
107+
令 n 为数组长度
108+
109+
- 时间复杂度:$O(nlogn)$
110+
- 空间复杂度:$O(n)$
111+
112+
主要的时间在于排序。
113+

‎problems/2866.beautiful-towers-ii.md

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
## 题目地址(2866. 美丽塔 II)
2+
3+
https://leetcode.cn/problems/beautiful-towers-ii/description/
4+
5+
## 题目描述
6+
7+
```
8+
给你一个长度为 n 下标从 0 开始的整数数组 maxHeights 。
9+
10+
你的任务是在坐标轴上建 n 座塔。第 i 座塔的下标为 i ,高度为 heights[i] 。
11+
12+
如果以下条件满足,我们称这些塔是 美丽 的:
13+
14+
1 <= heights[i] <= maxHeights[i]
15+
heights 是一个 山状 数组。
16+
如果存在下标 i 满足以下条件,那么我们称数组 heights 是一个 山状 数组:
17+
18+
对于所有 0 < j <= i ,都有 heights[j - 1] <= heights[j]
19+
对于所有 i <= k < n - 1 ,都有 heights[k + 1] <= heights[k]
20+
请你返回满足 美丽塔 要求的方案中,高度和的最大值 。
21+
22+
23+
24+
示例 1:
25+
26+
输入:maxHeights = [5,3,4,1,1]
27+
输出:13
28+
解释:和最大的美丽塔方案为 heights = [5,3,3,1,1] ,这是一个美丽塔方案,因为:
29+
- 1 <= heights[i] <= maxHeights[i]
30+
- heights 是个山状数组,峰值在 i = 0 处。
31+
13 是所有美丽塔方案中的最大高度和。
32+
示例 2:
33+
34+
输入:maxHeights = [6,5,3,9,2,7]
35+
输出:22
36+
解释: 和最大的美丽塔方案为 heights = [3,3,3,9,2,2] ,这是一个美丽塔方案,因为:
37+
- 1 <= heights[i] <= maxHeights[i]
38+
- heights 是个山状数组,峰值在 i = 3 处。
39+
22 是所有美丽塔方案中的最大高度和。
40+
示例 3:
41+
42+
输入:maxHeights = [3,2,5,5,2,3]
43+
输出:18
44+
解释:和最大的美丽塔方案为 heights = [2,2,5,5,2,2] ,这是一个美丽塔方案,因为:
45+
- 1 <= heights[i] <= maxHeights[i]
46+
- heights 是个山状数组,最大值在 i = 2 处。
47+
注意,在这个方案中,i = 3 也是一个峰值。
48+
18 是所有美丽塔方案中的最大高度和。
49+
50+
51+
提示:
52+
53+
1 <= n == maxHeights <= 105
54+
1 <= maxHeights[i] <= 109
55+
```
56+
57+
## 前置知识
58+
59+
- 动态规划
60+
- 单调栈
61+
62+
## 思路
63+
64+
这是一个为数不多的 2000 多分的中等题,难度在中等中偏大。
65+
66+
枚举 i 作为顶峰,其取值贪心的取 maxHeight[i]。关键是左右两侧如何取。由于左右两侧逻辑没有本质区别, 不妨仅考虑左边,然后套用同样的方法处理右边。
67+
68+
定义 f[i] 表示 i 为峰顶,左侧高度和最大值。我们可以递推地计算出所有 f[i] 的值。同理 g[i] 表示 i 为峰顶,右侧高度和最大值。
69+
70+
当 f 和 g 都已经处理好了,那么枚举 f[i] + g[i] - maxHeight[i] 的最大值即可。之所以减去 maxHeight[i] 是因为 f[i] 和 g[i] 都加上了当前位置的高度 maxHeight[i],重复了。
71+
72+
那么现在剩下如何计算 f 数组,也就是递推公式是什么。
73+
74+
我们用一个单调栈维护处理过的位置,对于当前位置 i,假设其左侧第一个小于它的位置是 l,那么 [l + 1, i] 都是大于等于 maxHeight[i] 的, 都可以且最多取到 maxHeight[i]。可以得到递推公式 f[i] = f[l] + (i - l) * maxHeight[i]
75+
76+
77+
## 代码
78+
79+
- 语言支持:Python3
80+
81+
Python3 Code:
82+
83+
```python
84+
class Solution:
85+
def maximumSumOfHeights(self, maxHeight: List[int]) -> int:
86+
# 枚举 i 作为顶峰,其取值贪心的取 maxHeight[i]
87+
# 其左侧第一个小于它的位置 l,[l + 1, i] 都可以且最多取到 maxHeight[i]
88+
n = len(maxHeight)
89+
f = [-1] * n # f[i] 表示 i 为峰顶,左侧高度和最大值
90+
g = [-1] * n # g[i] 表示 i 为峰顶,右侧高度和最大值
91+
def cal(f):
92+
st = []
93+
for i in range(len(maxHeight)):
94+
while st and maxHeight[i] < maxHeight[st[-1]]:
95+
st.pop()
96+
# 其左侧第一个小于它的位置 l,[l + 1, i] 都可以且最多取到 maxHeight[i]
97+
if st:
98+
f[i] = (i - st[-1]) * maxHeight[i] + f[st[-1]]
99+
else:
100+
f[i] = maxHeight[i] * (i + 1)
101+
st.append(i)
102+
cal(f)
103+
maxHeight = maxHeight[::-1]
104+
cal(g)
105+
maxHeight = maxHeight[::-1]
106+
ans = 0
107+
for i in range(len(maxHeight)):
108+
ans = max(ans, f[i] + g[n - 1 - i] - maxHeight[i])
109+
return ans
110+
```
111+
112+
113+
**复杂度分析**
114+
115+
令 n 为数组长度
116+
117+
- 时间复杂度:$O(n)$
118+
- 空间复杂度:$O(n)$
119+
120+
f 和 g 以及 st 都使用 n 的空间。并且我们仅遍历了 maxHeights 数组三次,因此时间和空间复杂度都是 n。
121+

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /