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 5e25e93

Browse files
feat: add solutions to lc problems: No.3224,3228 (doocs#3299)
* No.3224.Minimum Array Changes to Make Differences Equal * No.3228.Maximum Number of Operations to Move Ones to the End
1 parent 25448d6 commit 5e25e93

File tree

21 files changed

+803
-288
lines changed

21 files changed

+803
-288
lines changed

‎solution/1600-1699/1674.Minimum Moves to Make Array Complementary/README.md‎

Lines changed: 85 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -76,27 +76,33 @@ nums[3] + nums[0] = 3 + 1 = 4.
7676

7777
### 方法一:差分数组
7878

79-
我们不妨设 $a$ 为 $nums[i]$ 和 $nums[n-i-1]$ 的较小值,设 $b$ 为 $nums[i]$ 和 $nums[n-i-1]$ 的较大值
79+
假设最终的数组中,数对 $\textit{nums}[i]$ 和 $\textit{nums}[n-i-1]$ 的和为 $s$
8080

81-
假设经过替换后,两数之和为 $x$。由题意,我们知道 $x$ 最小值为 2ドル,ドル即两个数替换为 1ドル$;最大值为 2ドル \times limit,ドル即两个数都替换为 $limit$。因此 $x$ 的取值范围是 $[2,... 2 \times limit]$
81+
我们不妨设 $x$ 为 $\textit{nums}[i]$ 和 $\textit{nums}[n-i-1]$ 的较小值,设 $y$ 为 $\textit{nums}[i]$ 和 $\textit{nums}[n-i-1]$ 的较大值
8282

83-
如何求出对于不同的 $x,ドル需要替换的最少次数呢?
83+
对于每一对数,我们有以下几种情况:
8484

85-
我们分析发现:
85+
- 如果不需要替换,那么 $x + y = s$。
86+
- 如果替换一次,那么 $x + 1 \le s \le y + \textit{limit}$。
87+
- 如果替换两次,那么 2ドル \le s \le x$ 或 $y + \textit{limit} + 1 \le s \le 2 \times \textit{limit}$。
8688

87-
- 如果 $x = a + b,ドル那么我们需要替换的次数为 0ドル,ドル即当前的数对已经满足互补的要求;
88-
- 否则如果 1ドル + a \le x \le limit + b ,ドル那么我们需要替换的次数为 1ドル,ドル即把其中一个数替换即可;
89-
- 否则如果 2ドル \le x \le 2 \times limit,ドル那么我们需要替换的次数为 2ドル,ドル即把两个数都替换。
89+
即:
9090

91-
因此,我们可以遍历每一对数,执行如下操作:
91+
- 在 $[2,..x]$ 范围内,需要替换 2ドル$ 次。
92+
- 在 $[x+1,..x+y-1]$ 范围内,需要替换 1ドル$ 次。
93+
- 在 $[x+y]$ 时,不需要替换。
94+
- 在 $[x+y+1,..y + \textit{limit}]$ 范围内,需要替换 1ドル$ 次。
95+
- 在 $[y + \textit{limit} + 1,..2 \times \textit{limit}]$ 范围内,需要替换 2ドル$ 次。
9296

93-
1. 先将 $[2,... 2 \times limit]$ 范围需要的操作次数加 2ドル$。
94-
1. 再将 $[1 + a,... limit + b]$ 范围需要的操作次数减 1ドル$。
95-
1. 最后将 $[a + b,... a + b]$ 范围需要的操作次数减 1ドル$。
97+
我们枚举每一个数对,利用差分数组,更新每个数对在不同区间范围内的替换次数。
9698

97-
可以发现,这实际上是在对一个连续区间内的元素进行加减操作,因此我们可以使用差分数组来实现
99+
最后,我们求出下标 2ドル$ 到 2ドル \times \textit{limit}$ 的前缀和中的最小值,即为最少的替换次数
98100

99-
时间复杂度 $O(n),ドル空间复杂度 $O(n)$。其中 $n$ 为数组 $nums$ 的长度。
101+
时间复杂度 $O(n),ドル空间复杂度 $O(n)$。其中 $n$ 为数组 $\textit{nums}$ 的长度。
102+
103+
相似题目:
104+
105+
- [3224. 使差值相等的最少数组改动次数](https://github.com/doocs/leetcode/blob/main/solution/3200-3299/3224.Minimum%20Array%20Changes%20to%20Make%20Differences%20Equal/README.md)
100106

101107
<!-- tabs:start -->
102108

@@ -105,55 +111,44 @@ nums[3] + nums[0] = 3 + 1 = 4.
105111
```python
106112
class Solution:
107113
def minMoves(self, nums: List[int], limit: int) -> int:
108-
d = [0] * (limit * 2 + 2)
114+
d = [0] * (2 * limit + 2)
109115
n = len(nums)
110-
111-
for i inrange(n >>1):
112-
a, b =min(nums[i], nums[n - i -1]), max(nums[i], nums[n - i -1])
113-
116+
for i inrange(n //2):
117+
x, y = nums[i], nums[-i -1]
118+
if x > y:
119+
x, y = y, x
114120
d[2] += 2
115-
d[limit * 2 + 1] -= 2
116-
117-
d[a + 1] -= 1
118-
d[b + limit + 1] += 1
119-
120-
d[a + b] -= 1
121-
d[a + b + 1] += 1
122-
123-
ans, s = n, 0
124-
for v in d[2 : limit * 2 + 1]:
125-
s += v
126-
if ans > s:
127-
ans = s
128-
return ans
121+
d[x + 1] -= 2
122+
d[x + 1] += 1
123+
d[x + y] -= 1
124+
d[x + y + 1] += 1
125+
d[y + limit + 1] -= 1
126+
d[y + limit + 1] += 2
127+
return min(accumulate(d[2:]))
129128
```
130129

131130
#### Java
132131

133132
```java
134133
class Solution {
135134
public int minMoves(int[] nums, int limit) {
135+
int[] d = new int[2 * limit + 2];
136136
int n = nums.length;
137-
int[] d = new int[limit * 2 + 2];
138-
for (int i = 0; i < n >> 1; ++i) {
139-
int a = Math.min(nums[i], nums[n - i - 1]);
140-
int b = Math.max(nums[i], nums[n - i - 1]);
141-
137+
for (int i = 0; i < n / 2; ++i) {
138+
int x = Math.min(nums[i], nums[n - i - 1]);
139+
int y = Math.max(nums[i], nums[n - i - 1]);
142140
d[2] += 2;
143-
d[limit * 2 + 1] -= 2;
144-
145-
d[a + 1] -= 1;
146-
d[b + limit + 1] += 1;
147-
148-
d[a + b] -= 1;
149-
d[a + b + 1] += 1;
141+
d[x + 1] -= 2;
142+
d[x + 1] += 1;
143+
d[x + y] -= 1;
144+
d[x + y + 1] += 1;
145+
d[y + limit + 1] -= 1;
146+
d[y + limit + 1] += 2;
150147
}
151-
int ans = n, s =0;
152-
for (int i = 2; i <= limit *2; ++i) {
148+
int ans = n;
149+
for (int i = 2, s =0; i < d.length; ++i) {
153150
s += d[i];
154-
if (ans > s) {
155-
ans = s;
156-
}
151+
ans = Math.min(ans, s);
157152
}
158153
return ans;
159154
}
@@ -167,26 +162,25 @@ class Solution {
167162
public:
168163
int minMoves(vector<int>& nums, int limit) {
169164
int n = nums.size();
170-
vector<int> d(limit * 2 + 2);
171-
for (int i = 0; i < n >> 1; ++i) {
172-
int a = min(nums[i], nums[n - i - 1]);
173-
int b = max(nums[i], nums[n - i - 1]);
174-
165+
int d[limit * 2 + 2];
166+
memset(d, 0, sizeof(d));
167+
for (int i = 0; i < n / 2; ++i) {
168+
int x = nums[i], y = nums[n - i - 1];
169+
if (x > y) {
170+
swap(x, y);
171+
}
175172
d[2] += 2;
176-
d[limit * 2 + 1] -= 2;
177-
178-
d[a + 1] -= 1;
179-
d[b + limit + 1] += 1;
180-
181-
d[a + b] -= 1;
182-
d[a + b + 1] += 1;
173+
d[x + 1] -= 2;
174+
d[x + 1] += 1;
175+
d[x + y] -= 1;
176+
d[x + y + 1] += 1;
177+
d[y + limit + 1] -= 1;
178+
d[y + limit + 1] += 2;
183179
}
184-
int ans = n, s = 0;
185-
for (int i = 2; i <= limit * 2; ++i) {
180+
int ans = n;
181+
for (int i = 2, s = 0; i <= limit * 2; ++i) {
186182
s += d[i];
187-
if (ans > s) {
188-
ans = s;
189-
}
183+
ans = min(ans, s);
190184
}
191185
return ans;
192186
}
@@ -197,25 +191,25 @@ public:
197191
198192
```go
199193
func minMoves(nums []int, limit int) int {
200-
d := make([]int, limit*2+2)
201194
n := len(nums)
202-
for i := 0; i < n>>1; i++ {
203-
a, b := min(nums[i], nums[n-i-1]), max(nums[i], nums[n-i-1])
195+
d := make([]int, 2*limit+2)
196+
for i := 0; i < n/2; i++ {
197+
x, y := nums[i], nums[n-1-i]
198+
if x > y {
199+
x, y = y, x
200+
}
204201
d[2] += 2
205-
d[limit*2+1] -= 2
206-
207-
d[a+1] -= 1
208-
d[b+limit+1] += 1
209-
210-
d[a+b] -= 1
211-
d[a+b+1] += 1
202+
d[x+1] -= 2
203+
d[x+1] += 1
204+
d[x+y] -= 1
205+
d[x+y+1] += 1
206+
d[y+limit+1] -= 1
207+
d[y+limit+1] += 2
212208
}
213209
ans, s := n, 0
214-
for _, v := range d[2 : limit*2+1] {
215-
s += v
216-
if ans > s {
217-
ans = s
218-
}
210+
for _, x := range d[2:] {
211+
s += x
212+
ans = min(ans, s)
219213
}
220214
return ans
221215
}
@@ -228,25 +222,21 @@ function minMoves(nums: number[], limit: number): number {
228222
const n = nums.length;
229223
const d: number[] = Array(limit * 2 + 2).fill(0);
230224
for (let i = 0; i < n >> 1; ++i) {
231-
const a = Math.min(nums[i], nums[n - i - 1]);
232-
const b = Math.max(nums[i], nums[n - i - 1]);
233-
225+
const x = Math.min(nums[i], nums[n - 1 - i]);
226+
const y = Math.max(nums[i], nums[n - 1 - i]);
234227
d[2] += 2;
235-
d[limit * 2 + 1] -= 2;
236-
237-
d[a + 1] -= 1;
238-
d[b + limit + 1] += 1;
239-
240-
d[a + b] -= 1;
241-
d[a + b + 1] += 1;
228+
d[x + 1] -= 2;
229+
d[x + 1] += 1;
230+
d[x + y] -= 1;
231+
d[x + y + 1] += 1;
232+
d[y + limit + 1] -= 1;
233+
d[y + limit + 1] += 2;
242234
}
243235
let ans = n;
244236
let s = 0;
245-
for (let i = 2; i <=limit*2; ++i) {
237+
for (let i = 2; i <d.length; ++i) {
246238
s += d[i];
247-
if (ans > s) {
248-
ans = s;
249-
}
239+
ans = Math.min(ans, s);
250240
}
251241
return ans;
252242
}

0 commit comments

Comments
(0)

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