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 d301385

Browse files
author
robot
committed
feat: 3082ドル
1 parent f0a995d commit d301385

File tree

1 file changed

+168
-0
lines changed

1 file changed

+168
-0
lines changed
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
2+
## 题目地址(3082. 求出所有子序列的能量和 - 力扣(LeetCode))
3+
4+
https://leetcode.cn/problems/find-the-sum-of-the-power-of-all-subsequences/
5+
6+
## 题目描述
7+
8+
<p>给你一个长度为 <code>n</code>&nbsp;的整数数组&nbsp;<code>nums</code>&nbsp;和一个 <strong>正</strong>&nbsp;整数&nbsp;<code>k</code>&nbsp;。</p>
9+
10+
<p>一个整数数组的 <strong>能量</strong>&nbsp;定义为和 <strong>等于</strong>&nbsp;<code>k</code>&nbsp;的子序列的数目。</p>
11+
12+
<p>请你返回 <code>nums</code>&nbsp;中所有子序列的 <strong>能量和</strong>&nbsp;。</p>
13+
14+
<p>由于答案可能很大,请你将它对&nbsp;<code>10<sup>9</sup> + 7</code>&nbsp;<strong>取余</strong>&nbsp;后返回。</p>
15+
16+
<p>&nbsp;</p>
17+
18+
<p><strong class="example">示例 1:</strong></p>
19+
20+
<div class="example-block" style="border-color: var(--border-tertiary); border-left-width: 2px; color: var(--text-secondary); font-size: 0.875rem; margin-bottom: 1rem; margin-top: 1rem; overflow: visible; padding-left: 1rem;">
21+
<p><strong>输入:</strong> <span class="example-io" style="font-family: Menlo, sans-serif; font-size: 0.85rem;"> nums = [1,2,3], k = 3 </span></p>
22+
23+
<p><strong>输出:</strong> <span class="example-io" style="font-family: Menlo, sans-serif; font-size: 0.85rem;"> 6 </span></p>
24+
25+
<p><strong>解释:</strong></p>
26+
27+
<p>总共有&nbsp;<code>5</code>&nbsp;个能量不为 0 的子序列:</p>
28+
29+
<ul>
30+
<li>子序列&nbsp;<code>[<u><em><strong>1</strong></em></u>,<u><em><strong>2</strong></em></u>,<u><em><strong>3</strong></em></u>]</code> 有&nbsp;<code>2</code>&nbsp;个和为&nbsp;<code>3</code>&nbsp;的子序列:<code>[1,2,<u><strong><em>3</em></strong></u>]</code> 和 <code>[<u><strong><em>1</em></strong></u>,<u><strong><em>2</em></strong></u>,3]</code>&nbsp;。</li>
31+
<li>子序列&nbsp;<code>[<u><em><strong>1</strong></em></u>,2,<u><em><strong>3</strong></em></u>]</code>&nbsp;有 <code>1</code>&nbsp;个和为&nbsp;<code>3</code>&nbsp;的子序列:<code>[1,2,<u><strong><em>3</em></strong></u>]</code>&nbsp;。</li>
32+
<li>子序列&nbsp;<code>[1,<u><em><strong>2</strong></em></u>,<u><em><strong>3</strong></em></u>]</code> 有&nbsp;<code>1</code>&nbsp;个和为&nbsp;<code>3</code>&nbsp;的子序列:<code>[1,2,<u><strong><em>3</em></strong></u>]</code>&nbsp;。</li>
33+
<li>子序列&nbsp;<code>[<u><em><strong>1</strong></em></u>,<u><em><strong>2</strong></em></u>,3]</code>&nbsp;有&nbsp;<code>1</code>&nbsp;个和为&nbsp;<code>3</code>&nbsp;的子序列:<code>[<u><strong><em>1</em></strong></u>,<u><strong><em>2</em></strong></u>,3]</code>&nbsp;。</li>
34+
<li>子序列&nbsp;<code>[1,2,<u><em><strong>3</strong></em></u>]</code>&nbsp;有&nbsp;<code>1</code>&nbsp;个和为&nbsp;<code>3</code>&nbsp;的子序列:<code>[1,2,<u><strong><em>3</em></strong></u>]</code>&nbsp;。</li>
35+
</ul>
36+
37+
<p>所以答案为&nbsp;<code>2 +たす 1 +たす 1 +たす 1 +たす 1 = 6</code>&nbsp;。</p>
38+
</div>
39+
40+
<p><strong class="example">示例 2:</strong></p>
41+
42+
<div class="example-block" style="border-color: var(--border-tertiary); border-left-width: 2px; color: var(--text-secondary); font-size: 0.875rem; margin-bottom: 1rem; margin-top: 1rem; overflow: visible; padding-left: 1rem;">
43+
<p><strong>输入:</strong> <span class="example-io" style="font-family: Menlo, sans-serif; font-size: 0.85rem;"> nums = [2,3,3], k = 5 </span></p>
44+
45+
<p><strong>输出:</strong> <span class="example-io" style="font-family: Menlo, sans-serif; font-size: 0.85rem;"> 4 </span></p>
46+
47+
<p><strong>解释:</strong></p>
48+
49+
<p>总共有&nbsp;<code>3</code>&nbsp;个能量不为 0 的子序列:</p>
50+
51+
<ul>
52+
<li>子序列&nbsp;<code>[<u><em><strong>2</strong></em></u>,<u><em><strong>3</strong></em></u>,<u><em><strong>3</strong></em></u>]</code>&nbsp;有 2 个子序列和为&nbsp;<code>5</code>&nbsp;:<code>[<u><strong><em>2</em></strong></u>,3,<u><strong><em>3</em></strong></u>]</code> 和&nbsp;<code>[<u><strong><em>2</em></strong></u>,<u><strong><em>3</em></strong></u>,3]</code>&nbsp;。</li>
53+
<li>子序列&nbsp;<code>[<u><em><strong>2</strong></em></u>,3,<u><em><strong>3</strong></em></u>]</code>&nbsp;有 1 个子序列和为&nbsp;<code>5</code>&nbsp;:<code>[<u><strong><em>2</em></strong></u>,3,<u><strong><em>3</em></strong></u>]</code>&nbsp;。</li>
54+
<li>子序列&nbsp;<code>[<u><em><strong>2</strong></em></u>,<u><em><strong>3</strong></em></u>,3]</code>&nbsp;有 1 个子序列和为 <code>5</code>&nbsp;:<code>[<u><strong><em>2</em></strong></u>,<u><strong><em>3</em></strong></u>,3]</code>&nbsp;。</li>
55+
</ul>
56+
57+
<p>所以答案为&nbsp;<code>2 + 1 + 1 = 4</code>&nbsp;。</p>
58+
</div>
59+
60+
<p><strong class="example">示例 3:</strong></p>
61+
62+
<div class="example-block" style="border-color: var(--border-tertiary); border-left-width: 2px; color: var(--text-secondary); font-size: 0.875rem; margin-bottom: 1rem; margin-top: 1rem; overflow: visible; padding-left: 1rem;">
63+
<p><strong>输入:</strong> <span class="example-io" style="font-family: Menlo, sans-serif; font-size: 0.85rem;"> nums = [1,2,3], k = 7 </span></p>
64+
65+
<p><strong>输出:</strong> <span class="example-io" style="font-family: Menlo, sans-serif; font-size: 0.85rem;"> 0 </span></p>
66+
67+
<p><strong>解释:</strong>不存在和为 <code>7</code>&nbsp;的子序列,所以 <code>nums</code>&nbsp;的能量和为&nbsp;<code>0</code>&nbsp;。</p>
68+
</div>
69+
70+
<p>&nbsp;</p>
71+
72+
<p><strong>提示:</strong></p>
73+
74+
<ul>
75+
<li><code>1 &lt;= n &lt;= 100</code></li>
76+
<li><code>1 &lt;= nums[i] &lt;= 10<sup>4</sup></code></li>
77+
<li><code>1 &lt;= k &lt;= 100</code></li>
78+
</ul>
79+
80+
81+
## 前置知识
82+
83+
- 动态规划
84+
85+
## 公司
86+
87+
- 暂无
88+
89+
## 思路
90+
91+
主页里我提到过:"困难题目,从逻辑上说, 要么就是非常难想到,要么就是非常难写代码。 由于有时候需要组合多种算法,因此这部分题目的难度是最大的。"
92+
93+
这道题我们可以先尝试将问题分解,分解为若干相对简单的子问题。然后子问题合并求解出最终的答案。
94+
95+
比如我们可以先`求出和为 k 的子序列`,然后用**贡献法**的思想考虑当前和为 k 的子序列(不妨记做S)对答案的贡献。其对答案的贡献就是**有多少子序列T包含当前和为k的子序列S**。假设有 10 个子序列包含 S,那么子序列 S 对答案的贡献就是 10。
96+
97+
那么问题转化为了:
98+
99+
1. 求出和为 k 的子序列
100+
2. 求出包含某个子序列的子序列的个数
101+
102+
对于第一个问题,本质就是对于每一个元素选择或者不选择,可以通过动态规划相对轻松地求出。伪代码:
103+
104+
```py
105+
def f(i, k):
106+
if i == n:
107+
if k == 0: 找到了
108+
else: 没找到
109+
if k == 0:
110+
没找到
111+
f(i + 1, k) # 不选择
112+
f(i + 1, k - nums[i]) # 选择
113+
```
114+
115+
对于第二个问题,由于除了 S,**其他元素**都可以选择或者不选择,因此总共有 2ドル^{n-cnt}$ 种选择。其中 cnt 就是子序列 S 的长度。
116+
117+
两个问题结合起来,就可以求出答案了。具体可以看下面的代码。
118+
119+
## 关键点
120+
121+
- 分解问题
122+
123+
## 代码
124+
125+
- 语言支持:Python3
126+
127+
Python3 Code:
128+
129+
```python
130+
131+
class Solution:
132+
def sumOfPower(self, nums: List[int], k: int) -> int:
133+
n = len(nums)
134+
MOD = 10 ** 9 + 7
135+
@cache
136+
def dfs(i, k):
137+
if k == 0: return pow(2, n - i, MOD)
138+
if i == n or k < 0: return 0
139+
ans = dfs(i + 1, k) * 2 # 不选
140+
ans += dfs(i + 1, k - nums[i]) #
141+
return ans % MOD
142+
143+
return dfs(0, k)
144+
145+
```
146+
147+
148+
**复杂度分析**
149+
150+
令 n 为数组长度。
151+
152+
由于转移需要 O(1) 的时间,因此总时间复杂度为 O(n * k),除了存储递归结果的空间外,没有其他空间消耗,因此空间复杂度为 O(n * k)。
153+
154+
- 时间复杂度:$O(n * k)$
155+
- 空间复杂度:$O(n * k)$
156+
157+
158+
159+
160+
> 此题解由 [力扣刷题插件](https://leetcode-pp.github.io/leetcode-cheat/?tab=solution-template) 自动生成。
161+
162+
力扣的小伙伴可以[关注我](https://leetcode-cn.com/u/fe-lucifer/),这样就会第一时间收到我的动态啦~
163+
164+
以上就是本文的全部内容了。大家对此有何看法,欢迎给我留言,我有时间都会一一查看回答。更多算法套路可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 40K star 啦。大家也可以关注我的公众号《力扣加加》带你啃下算法这块硬骨头。
165+
166+
关注公众号力扣加加,努力用清晰直白的语言还原解题思路,并且有大量图解,手把手教你识别套路,高效刷题。
167+
168+
![](https://p.ipic.vip/h9nm77.jpg)

0 commit comments

Comments
(0)

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