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 8a59cad

Browse files
author
robot
committed
feat: 3229ドル
1 parent 5f7ad64 commit 8a59cad

File tree

1 file changed

+139
-0
lines changed

1 file changed

+139
-0
lines changed
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
2+
## 题目地址(3229. 使数组等于目标数组所需的最少操作次数 - 力扣(LeetCode))
3+
4+
https://leetcode.cn/problems/minimum-operations-to-make-array-equal-to-target/description/
5+
6+
## 题目描述
7+
8+
<p>给你两个长度相同的正整数数组 <code>nums</code> 和 <code>target</code>。</p>
9+
10+
<p>在一次操作中,你可以选择 <code>nums</code> 的任何<span data-keyword="subarray" class=" cursor-pointer relative text-dark-blue-s text-sm"><div class="popover-wrapper inline-block" data-headlessui-state=""><div><div aria-expanded="false" data-headlessui-state="" id="headlessui-popover-button-:r11:"><div>子数组</div></div><div style="position: fixed; z-index: 40; inset: 0px auto auto 0px; transform: translate(299px, 257px);"></div></div></div></span>,并将该子数组内的每个元素的值增加或减少 1。</p>
11+
12+
<p>返回使 <code>nums</code> 数组变为 <code>target</code> 数组所需的 <strong>最少 </strong>操作次数。</p>
13+
14+
<p>&nbsp;</p>
15+
16+
<p><strong class="example">示例 1:</strong></p>
17+
18+
<div class="example-block">
19+
<p><strong>输入:</strong> <span class="example-io">nums = [3,5,1,2], target = [4,6,2,4]</span></p>
20+
21+
<p><strong>输出:</strong> <span class="example-io">2</span></p>
22+
23+
<p><strong>解释:</strong></p>
24+
25+
<p>执行以下操作可以使 <code>nums</code> 等于 <code>target</code>:<br>
26+
- <code>nums[0..3]</code> 增加 1,<code>nums = [4,6,2,3]</code>。<br>
27+
- <code>nums[3..3]</code> 增加 1,<code>nums = [4,6,2,4]</code>。</p>
28+
</div>
29+
30+
<p><strong class="example">示例 2:</strong></p>
31+
32+
<div class="example-block">
33+
<p><strong>输入:</strong> <span class="example-io">nums = [1,3,2], target = [2,1,4]</span></p>
34+
35+
<p><strong>输出:</strong> <span class="example-io">5</span></p>
36+
37+
<p><strong>解释:</strong></p>
38+
39+
<p>执行以下操作可以使 <code>nums</code> 等于 <code>target</code>:<br>
40+
- <code>nums[0..0]</code> 增加 1,<code>nums = [2,3,2]</code>。<br>
41+
- <code>nums[1..1]</code> 减少 1,<code>nums = [2,2,2]</code>。<br>
42+
- <code>nums[1..1]</code> 减少 1,<code>nums = [2,1,2]</code>。<br>
43+
- <code>nums[2..2]</code> 增加 1,<code>nums = [2,1,3]</code>。<br>
44+
- <code>nums[2..2]</code> 增加 1,<code>nums = [2,1,4]</code>。</p>
45+
</div>
46+
47+
<p>&nbsp;</p>
48+
49+
<p><strong>提示:</strong></p>
50+
51+
<ul>
52+
<li><code>1 &lt;= nums.length == target.length &lt;= 10<sup>5</sup></code></li>
53+
<li><code>1 &lt;= nums[i], target[i] &lt;= 10<sup>8</sup></code></li>
54+
</ul>
55+
56+
57+
## 前置知识
58+
59+
-
60+
61+
## 公司
62+
63+
- 暂无
64+
65+
## 思路
66+
67+
这道题是 [1526. 形成目标数组的子数组最少增加次数](./1526.minimum-number-of-increments-on-subarrays-to-form-a-target-array.md) 的进阶版。我们的操作不仅可以 + 1, 也可以 - 1。
68+
69+
如果大家没有看过那篇题解的话,建议先看一下。后面的内容将会假设你看过那篇题解。
70+
71+
注意到我们仅关心 nums[i] 和 target[i] 的相对大小,且 nums 中的数相互独立。因此我们可以将差值记录到数组 diff 中,这样和 [1526. 形成目标数组的子数组最少增加次数](./1526.minimum-number-of-increments-on-subarrays-to-form-a-target-array.md) 更加一致。
72+
73+
前面那道题,数组没有负数。而我们生成的 diff 是可能为正数和负数的。这会有什么不同吗?
74+
75+
不妨考虑 diff[i] > 0 且 diff[i+1] < 0。我们的操作会横跨 i 和 i + 1 么?答案是不会,因为这两个操作相比**从i断开,直接再操作 diff[i+1]**不会使得总的结果更优。因此我们不妨就再变号的时候重新开始一段。
76+
77+
另外就是一个小小的细节。diff[i] 和diff[i+1] 都是负数的时候,如果:
78+
79+
- diff[i] <= diff[i+1] 意味着 diff[i+1] 可以顺便改了
80+
- diff[i] > diff[i+1] 意味着 diff[i+1] 需要再操作 diff[i] - diff[i+1]
81+
82+
这个判断和 diff[i] > 0 且 diff[i+1] 的时候完全是反的。我们可以通过取绝对值来统一逻辑,使得代码更加简洁。
83+
84+
至于其他的,基本就和上面的题目一样了。
85+
86+
## 关键点
87+
88+
- 考虑修改的左右端点
89+
- 正负交替的情况,可以直接新开一段
90+
91+
## 代码
92+
93+
- 语言支持:Python3
94+
95+
Python3 Code:
96+
97+
```python
98+
99+
class Solution:
100+
def minimumOperations(self, nums: List[int], target: List[int]) -> int:
101+
diff = []
102+
for i in range(len(nums)):
103+
diff.append(nums[i] - target[i])
104+
ans = abs(diff[0])
105+
for i in range(1, len(nums)):
106+
if diff[i] * diff[i - 1] >= 0: # 符号相同,可以贪心地复用
107+
if abs(diff[i]) > abs(diff[i - 1]): # 这种情况,说明前面不能顺便把我改了,还需要我操作一次
108+
ans += abs(diff[i]) - abs(diff[i - 1])
109+
else: # 符号不同,不可以复用,必须重新开启一段
110+
ans += abs(diff[i])
111+
return ans
112+
113+
114+
```
115+
116+
117+
**复杂度分析**
118+
119+
令 n 为数组长度。
120+
121+
- 时间复杂度:$O(n)$
122+
- 空间复杂度:$O(n)$
123+
124+
125+
126+
127+
> 此题解由 [力扣刷题插件](https://leetcode-pp.github.io/leetcode-cheat/?tab=solution-template) 自动生成。
128+
129+
力扣的小伙伴可以[关注我](https://leetcode-cn.com/u/fe-lucifer/),这样就会第一时间收到我的动态啦~
130+
131+
以上就是本文的全部内容了。大家对此有何看法,欢迎给我留言,我有时间都会一一查看回答。更多算法套路可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 54K star 啦。大家也可以关注我的公众号《力扣加加》带你啃下算法这块硬骨头。
132+
133+
关注公众号力扣加加,努力用清晰直白的语言还原解题思路,并且有大量图解,手把手教你识别套路,高效刷题。
134+
135+
![](https://p.ipic.vip/h9nm77.jpg)
136+
137+
## 相似题目
138+
139+
- [1526. 形成目标数组的子数组最少增加次数](./1526.minimum-number-of-increments-on-subarrays-to-form-a-target-array.md)

0 commit comments

Comments
(0)

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