Skip to content

Commit 8ba287b

Browse files
author
robot
committed
$2141,$2939
1 parent 6e477e5 commit 8ba287b

File tree

2 files changed

+264
-0
lines changed

2 files changed

+264
-0
lines changed

Diff for: problems/2141.maximum-running-time-of-n-computers.md

+134
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
## 题目地址(2141. 同时运行 N 台电脑的最长时间 - 力扣(LeetCode))
2+
3+
https://leetcode.cn/problems/maximum-running-time-of-n-computers/?utm_source=LCUS&utm_medium=ip_redirect&utm_campaign=transfer2china
4+
5+
## 题目描述
6+
7+
<p>你有&nbsp;<code>n</code>&nbsp;台电脑。给你整数&nbsp;<code>n</code>&nbsp;和一个下标从 <strong>0</strong>&nbsp;开始的整数数组&nbsp;<code>batteries</code>&nbsp;,其中第&nbsp;<code>i</code>&nbsp;个电池可以让一台电脑 <strong>运行&nbsp;</strong><code>batteries[i]</code>&nbsp;分钟。你想使用这些电池让&nbsp;<strong>全部</strong>&nbsp;<code>n</code>&nbsp;台电脑 <b>同时</b>&nbsp;运行。</p>
8+
9+
<p>一开始,你可以给每台电脑连接 <strong>至多一个电池</strong>&nbsp;。然后在任意整数时刻,你都可以将一台电脑与它的电池断开连接,并连接另一个电池,你可以进行这个操作 <strong>任意次</strong>&nbsp;。新连接的电池可以是一个全新的电池,也可以是别的电脑用过的电池。断开连接和连接新的电池不会花费任何时间。</p>
10+
11+
<p>注意,你不能给电池充电。</p>
12+
13+
<p>请你返回你可以让 <code>n</code>&nbsp;台电脑同时运行的 <strong>最长</strong>&nbsp;分钟数。</p>
14+
15+
<p>&nbsp;</p>
16+
17+
<p><strong>示例 1:</strong></p>
18+
19+
<p><img alt="" src="https://assets.leetcode.com/uploads/2022/01/06/example1-fit.png" style="width: 762px; height: 150px;"></p>
20+
21+
<pre><b>输入:</b>n = 2, batteries = [3,3,3]
22+
<b>输出:</b>4
23+
<b>解释:</b>
24+
一开始,将第一台电脑与电池 0 连接,第二台电脑与电池 1 连接。
25+
2 分钟后,将第二台电脑与电池 1 断开连接,并连接电池 2 。注意,电池 0 还可以供电 1 分钟。
26+
在第 3 分钟结尾,你需要将第一台电脑与电池 0 断开连接,然后连接电池 1 。
27+
在第 4 分钟结尾,电池 1 也被耗尽,第一台电脑无法继续运行。
28+
我们最多能同时让两台电脑同时运行 4 分钟,所以我们返回 4 。
29+
</pre>
30+
31+
<p><strong>示例 2:</strong></p>
32+
33+
<p><img alt="" src="https://assets.leetcode.com/uploads/2022/01/06/example2.png" style="width: 629px; height: 150px;"></p>
34+
35+
<pre><b>输入:</b>n = 2, batteries = [1,1,1,1]
36+
<b>输出:</b>2
37+
<b>解释:</b>
38+
一开始,将第一台电脑与电池 0 连接,第二台电脑与电池 2 连接。
39+
一分钟后,电池 0 和电池 2 同时耗尽,所以你需要将它们断开连接,并将电池 1 和第一台电脑连接,电池 3 和第二台电脑连接。
40+
1 分钟后,电池 1 和电池 3 也耗尽了,所以两台电脑都无法继续运行。
41+
我们最多能让两台电脑同时运行 2 分钟,所以我们返回 2 。
42+
</pre>
43+
44+
<p>&nbsp;</p>
45+
46+
<p><strong>提示:</strong></p>
47+
48+
<ul>
49+
<li><code>1 &lt;= n &lt;= batteries.length &lt;= 10<sup>5</sup></code></li>
50+
<li><code>1 &lt;= batteries[i] &lt;= 10<sup>9</sup></code></li>
51+
</ul>
52+
53+
## 前置知识
54+
55+
- 二分
56+
57+
## 公司
58+
59+
- 暂无
60+
61+
## 思路
62+
63+
我们可以将时间作为横坐标,电脑作为纵坐标,直观地用图来描述电池的分配情况。这位博主画了一个图,很直观,我直接借用了
64+
65+
![](https://p.ipic.vip/oup1k5.png)
66+
67+
题目给的例子 n = 2, batteries = [3,3,3] 很有启发。如果先将电池 0 和 电池 1 给两个电脑,然后剩下一个电池不能同时给两个电脑分配,因此这种分配不行。
68+
69+
那么具体如何分配呢? 我们其实不用关心,因为题目不需要给出具体的分配方案。而是给出具体的使用时间即可。
70+
71+
需要注意的是,只要电量够,那么一定可以找到一种分配方法。
72+
73+
电量够指的是:
74+
75+
- 对于一个电池,如果其电量大于 t,那么只能用 t。因为一个电池同时只能给一个电脑供电。
76+
- 对于一个电池,如果其电量小于等于 t,那么我们可以全部用掉。
77+
78+
合起来就是:sum([min(t, battery) for battery in batteries])
79+
80+
如果合起来大于等于需要的电量(这里是 n \* t),那么就一定可以有一种分配方案,使得能够运行 t 分钟。
81+
82+
如何证明一定可以找到这种办法呢?
83+
84+
对于 [3, 3, 3] n = 2 这个例子,我们可以调整最后 1 分钟的电池分配情况使得不重叠(不重叠指的是不存在一个电池需要同时给两个电脑供电的情况)。
85+
86+
那么如何调整?实际上只要任意和前面电池的 1 分钟进行交换,两个不重叠就好。
87+
88+
可以证明如果电池电量小于总运行时间 t,我们一定可以进行交换使得不重叠。如果大于 t,由于我们最多只能用到 t,因此 t 的部分能够交换不重叠, 而超过 t 的部分根本用不到,不用考虑。
89+
90+
大家也可以反着想。 **如果不存在**一种交换方式使得不重叠。那么说明至少有一个电池的运行时间大于 t,这与题目矛盾。(因为运行 t 时间, 电池不同给多个电脑供电,也就是说电池最多消耗 t 的电量)大家可以结合前面的图来进行理解。
91+
92+
## 关键点
93+
94+
- 证明总的可用电池大于等于总的分钟数是充要条件
95+
96+
## 代码
97+
98+
- 语言支持:Python3
99+
100+
Python3 Code:
101+
102+
```python
103+
104+
class Solution:
105+
def maxRunTime(self, n: int, batteries: List[int]) -> int:
106+
def can(k):
107+
return sum([min(k, battery) for battery in batteries]) >= n * k
108+
l, r = 0, sum(batteries)
109+
while l <= r:
110+
mid = (l + r) // 2
111+
if can(mid):
112+
l = mid + 1
113+
else:
114+
r = mid - 1
115+
return r
116+
117+
```
118+
119+
**复杂度分析**
120+
121+
令 n 为数组长度,C 为 batteries 数组的 n 项和。
122+
123+
- 时间复杂度:$O(nlogC)$
124+
- 空间复杂度:$O(1)$
125+
126+
> 此题解由 [力扣刷题插件](https://leetcode-pp.github.io/leetcode-cheat/?tab=solution-template) 自动生成。
127+
128+
力扣的小伙伴可以[关注我](https://leetcode-cn.com/u/fe-lucifer/),这样就会第一时间收到我的动态啦~
129+
130+
以上就是本文的全部内容了。大家对此有何看法,欢迎给我留言,我有时间都会一一查看回答。更多算法套路可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 40K star 啦。大家也可以关注我的公众号《力扣加加》带你啃下算法这块硬骨头。
131+
132+
关注公众号力扣加加,努力用清晰直白的语言还原解题思路,并且有大量图解,手把手教你识别套路,高效刷题。
133+
134+
![](https://p.ipic.vip/h9nm77.jpg)

Diff for: problems/2939.maximum-xor-product.md

+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
2+
## 题目地址(2939. 最大异或乘积 - 力扣(LeetCode))
3+
4+
https://leetcode.cn/problems/maximum-xor-product/
5+
6+
## 题目描述
7+
8+
<p>给你三个整数&nbsp;<code>a</code>&nbsp;,<code>b</code>&nbsp;&nbsp;<code>n</code>&nbsp;,请你返回&nbsp;<code>(a XOR x) * (b XOR x)</code>&nbsp;&nbsp;<strong>最大值</strong>&nbsp;且 <code>x</code>&nbsp;需要满足 <code>0 &lt;= x &lt; 2<sup>n</sup></code>。</p>
9+
10+
<p>由于答案可能会很大,返回它对&nbsp;<code>10<sup>9 </sup>+ 7</code>&nbsp;<strong>取余</strong>&nbsp;后的结果。</p>
11+
12+
<p><strong>注意</strong>,<code>XOR</code>&nbsp;是按位异或操作。</p>
13+
14+
<p>&nbsp;</p>
15+
16+
<p><strong class="example">示例 1:</strong></p>
17+
18+
<pre><b>输入:</b>a = 12, b = 5, n = 4
19+
<b>输出:</b>98
20+
<b>解释:</b>当 x = 2 时,(a XOR x) = 14 且 (b XOR x) = 7 。所以,(a XOR x) * (b XOR x) = 98 。
21+
98 是所有满足 0 &lt;= x &lt; 2<sup>n </sup>中 (a XOR x) * (b XOR x) 的最大值。
22+
</pre>
23+
24+
<p><strong class="example">示例 2:</strong></p>
25+
26+
<pre><b>输入:</b>a = 6, b = 7 , n = 5
27+
<b>输出:</b>930
28+
<b>解释:</b>当 x = 25 时,(a XOR x) = 31 且 (b XOR x) = 30 。所以,(a XOR x) * (b XOR x) = 930 。
29+
930 是所有满足 0 &lt;= x &lt; 2<sup>n </sup>中 (a XOR x) * (b XOR x) 的最大值。</pre>
30+
31+
<p><strong class="example">示例 3:</strong></p>
32+
33+
<pre><b>输入:</b>a = 1, b = 6, n = 3
34+
<b>输出:</b>12
35+
<b>解释: </b>当 x = 5 时,(a XOR x) = 4 且 (b XOR x) = 3 。所以,(a XOR x) * (b XOR x) = 12 。
36+
12 是所有满足 0 &lt;= x &lt; 2<sup>n </sup>中 (a XOR x) * (b XOR x) 的最大值。
37+
</pre>
38+
39+
<p>&nbsp;</p>
40+
41+
<p><strong>提示:</strong></p>
42+
43+
<ul>
44+
<li><code>0 &lt;= a, b &lt; 2<sup>50</sup></code></li>
45+
<li><code>0 &lt;= n &lt;= 50</code></li>
46+
</ul>
47+
48+
49+
## 前置知识
50+
51+
- 位运算
52+
53+
## 公司
54+
55+
- 暂无
56+
57+
## 思路
58+
59+
题目是求 a xor x 和 b xor x 的乘积最大。x 的取值范围是 0 <= x < 2^n。为了方便这里我们 a xor x 记做 axorx,b xor x 记做 bxorx,
60+
61+
首先我们要注意。对于除了低 n 位,其他位不受 x 异或影响。因为 x 除了低 n 可能不是 1,其他位都是 0。而 0 与任何数异或还是自身,不会改变。
62+
63+
因此我们能改的只是低 n 位。那么 x 的低 n 位具体去多少才可以呢?
64+
65+
朴素地枚举每一位上是 0 还是 1 的时间复杂度是 $2^n$,无法通过。
66+
67+
我们不妨逐位考虑。对于每一位:
68+
69+
- 如果 a 和 b 在当前位相同, 那么 x 只要和其取相反的就行,异或答案就是 1。
70+
- 如果 a 和 b 在当前位不同, 那么 axorx 在当前位的值与bxorx 在当前位的值吧必然一个是 0 一个是 1,那么让哪个是 1,哪个是 0 才能使得乘积最大么?
71+
72+
根据初中的知识,对于和相同的两个数,两者数相差的越小乘积越大。因此我们的策略就是 axorx 和 bxorx 哪个小就让他大一点,这样可以使得两者差更小。
73+
74+
那么没有最终计算出来 axorx 和 bxorx,怎么提前知道哪个大哪个小呢?其实我们可以从高位往低位遍历,这样不用具体算出来 axorx 和 bxorx 也能知道大小关系啦。
75+
76+
77+
## 关键点
78+
79+
- 除了低 n 位,其他不受 x 异或影响
80+
- 对于每一位,贪心地使得异或结果为 1, 如果不能,贪心地使较小的异或结果为 1
81+
82+
## Code
83+
84+
- 语言支持:Python3
85+
86+
Python3 Code:
87+
88+
```python
89+
90+
class Solution:
91+
def maximumXorProduct(self, a: int, b: int, n: int) -> int:
92+
axorx = (a >> n) << n # 低 n 位去掉,剩下的前 m 位就是答案中的 axorb 二进制位。剩下要做的是确定低 n 位具体是多少
93+
bxorx = (b >> n) << n
94+
MOD = 10 ** 9 + 7
95+
for i in range(n-1, -1, -1):
96+
t1 = a >> i & 1
97+
t2 = b >> i & 1
98+
if t1 == t2:
99+
axorx |= 1 << i
100+
bxorx |= 1 << i
101+
else:
102+
if axorx < bxorx:
103+
axorx |= 1 << i # 和一定,两者相差越小,乘积越大
104+
else:
105+
bxorx |= 1 << i
106+
axorx %= MOD
107+
bxorx %= MOD
108+
return (axorx * bxorx) % MOD
109+
110+
```
111+
112+
113+
**复杂度分析**
114+
115+
116+
- 时间复杂度:$O(n)$
117+
- 空间复杂度:$O(1)$
118+
119+
120+
121+
122+
> 此题解由 [力扣刷题插件](https://leetcode-pp.github.io/leetcode-cheat/?tab=solution-template) 自动生成。
123+
124+
力扣的小伙伴可以[关注我](https://leetcode-cn.com/u/fe-lucifer/),这样就会第一时间收到我的动态啦~
125+
126+
以上就是本文的全部内容了。大家对此有何看法,欢迎给我留言,我有时间都会一一查看回答。更多算法套路可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 40K star 啦。大家也可以关注我的公众号《力扣加加》带你啃下算法这块硬骨头。
127+
128+
关注公众号力扣加加,努力用清晰直白的语言还原解题思路,并且有大量图解,手把手教你识别套路,高效刷题。
129+
130+
![](https://p.ipic.vip/h9nm77.jpg)

0 commit comments

Comments
 (0)