Skip to content

Commit 9d07754

Browse files
committed
feat: add solutions to lc problem: No.1674
No.1674.Minimum Moves to Make Array Complementary
1 parent 5cbddcf commit 9d07754

File tree

6 files changed

+385
-0
lines changed

6 files changed

+385
-0
lines changed

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

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,22 +58,169 @@ nums[3] + nums[0] = 3 + 1 = 4.
5858

5959
<!-- 这里可写通用的实现逻辑 -->
6060

61+
**方法一:差分数组**
62+
63+
我们不妨设 $a$ 为 $nums[i]$ 和 $nums[n-i-1]$ 的较小值,设 $b$ 为 $nums[i]$ 和 $nums[n-i-1]$ 的较大值。
64+
65+
假设经过替换后,两数之和为 $x$。由题意,我们知道 $x$ 最小值为 $2$,即两个数替换为 $1$;最大值为 $2 \times limit$,即两个数都替换为 $limit$。因此 $x$ 的取值范围是 $[2,... 2 \times limit]$。
66+
67+
如何求出对于不同的 $x$,需要替换的最少次数呢?
68+
69+
我们分析发现:
70+
71+
- 如果 $x = a + b$,那么我们需要替换的次数为 $0$,即当前的数对已经满足互补的要求;
72+
- 否则如果 $1 + a \le x \le limit + b $,那么我们需要替换的次数为 $1$,即把其中一个数替换即可;
73+
- 否则如果 $2 \le x \le 2 \times limit$,那么我们需要替换的次数为 $2$,即把两个数都替换。
74+
75+
因此,我们可以遍历每一对数,执行如下操作:
76+
77+
1. 先将 $[2,... 2 \times limit]$ 范围需要的操作次数加 $2$。
78+
1. 再将 $[1 + a,... limit + b]$ 范围需要的操作次数减 $1$。
79+
1. 最后将 $[a + b,... a + b]$ 范围需要的操作次数减 $1$。
80+
81+
可以发现,这实际上是在对一个连续区间内的元素进行加减操作,因此我们可以使用差分数组来实现。
82+
83+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 `nums` 的长度。
84+
6185
<!-- tabs:start -->
6286

6387
### **Python3**
6488

6589
<!-- 这里可写当前语言的特殊实现逻辑 -->
6690

6791
```python
92+
class Solution:
93+
def minMoves(self, nums: List[int], limit: int) -> int:
94+
d = [0] * (limit * 2 + 2)
95+
n = len(nums)
96+
97+
for i in range(n >> 1):
98+
a, b = min(nums[i], nums[n - i - 1]), max(nums[i], nums[n - i - 1])
99+
100+
d[2] += 2
101+
d[limit * 2 + 1] -= 2
102+
103+
d[a + 1] -= 1
104+
d[b + limit + 1] += 1
68105

106+
d[a + b] -= 1
107+
d[a + b + 1] += 1
108+
109+
ans, s = n, 0
110+
for v in d[2: limit * 2 + 1]:
111+
s += v
112+
if ans > s:
113+
ans = s
114+
return ans
69115
```
70116

71117
### **Java**
72118

73119
<!-- 这里可写当前语言的特殊实现逻辑 -->
74120

75121
```java
122+
class Solution {
123+
public int minMoves(int[] nums, int limit) {
124+
int n = nums.length;
125+
int[] d = new int[limit * 2 + 2];
126+
for (int i = 0; i < n >> 1; ++i) {
127+
int a = Math.min(nums[i], nums[n - i - 1]);
128+
int b = Math.max(nums[i], nums[n - i - 1]);
129+
130+
d[2] += 2;
131+
d[limit * 2 + 1] -= 2;
132+
133+
d[a + 1] -= 1;
134+
d[b + limit + 1] += 1;
135+
136+
d[a + b] -= 1;
137+
d[a + b + 1] += 1;
138+
}
139+
int ans = n, s = 0;
140+
for (int i = 2; i <= limit * 2; ++i) {
141+
s += d[i];
142+
if (ans > s) {
143+
ans = s;
144+
}
145+
}
146+
return ans;
147+
}
148+
}
149+
```
150+
151+
### **C++**
152+
153+
```cpp
154+
class Solution {
155+
public:
156+
int minMoves(vector<int>& nums, int limit) {
157+
int n = nums.size();
158+
vector<int> d(limit * 2 + 2);
159+
for (int i = 0; i < n >> 1; ++i) {
160+
int a = min(nums[i], nums[n - i - 1]);
161+
int b = max(nums[i], nums[n - i - 1]);
162+
163+
d[2] += 2;
164+
d[limit * 2 + 1] -= 2;
165+
166+
d[a + 1] -= 1;
167+
d[b + limit + 1] += 1;
168+
169+
d[a + b] -= 1;
170+
d[a + b + 1] += 1;
171+
}
172+
int ans = n, s = 0;
173+
for (int i = 2; i <= limit * 2; ++i) {
174+
s += d[i];
175+
if (ans > s) {
176+
ans = s;
177+
}
178+
}
179+
return ans;
180+
}
181+
};
182+
```
76183

184+
### **Go**
185+
186+
```go
187+
func minMoves(nums []int, limit int) int {
188+
d := make([]int, limit*2+2)
189+
n := len(nums)
190+
for i := 0; i < n>>1; i++ {
191+
a, b := min(nums[i], nums[n-i-1]), max(nums[i], nums[n-i-1])
192+
d[2] += 2
193+
d[limit*2+1] -= 2
194+
195+
d[a+1] -= 1
196+
d[b+limit+1] += 1
197+
198+
d[a+b] -= 1
199+
d[a+b+1] += 1
200+
}
201+
ans, s := n, 0
202+
for _, v := range d[2 : limit*2+1] {
203+
s += v
204+
if ans > s {
205+
ans = s
206+
}
207+
}
208+
return ans
209+
}
210+
211+
func max(a, b int) int {
212+
if a > b {
213+
return a
214+
}
215+
return b
216+
}
217+
218+
func min(a, b int) int {
219+
if a < b {
220+
return a
221+
}
222+
return b
223+
}
77224
```
78225

79226
### **...**

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

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,136 @@ Therefore, nums[i] + nums[n-1-i] = 4 for every i, so nums is complementary.
5757
### **Python3**
5858

5959
```python
60+
class Solution:
61+
def minMoves(self, nums: List[int], limit: int) -> int:
62+
d = [0] * (limit * 2 + 2)
63+
n = len(nums)
6064

65+
for i in range(n >> 1):
66+
a, b = min(nums[i], nums[n - i - 1]), max(nums[i], nums[n - i - 1])
67+
68+
d[2] += 2
69+
d[limit * 2 + 1] -= 2
70+
71+
d[a + 1] -= 1
72+
d[b + limit + 1] += 1
73+
74+
d[a + b] -= 1
75+
d[a + b + 1] += 1
76+
77+
ans, s = n, 0
78+
for v in d[2: limit * 2 + 1]:
79+
s += v
80+
if ans > s:
81+
ans = s
82+
return ans
6183
```
6284

6385
### **Java**
6486

6587
```java
88+
class Solution {
89+
public int minMoves(int[] nums, int limit) {
90+
int n = nums.length;
91+
int[] d = new int[limit * 2 + 2];
92+
for (int i = 0; i < n >> 1; ++i) {
93+
int a = Math.min(nums[i], nums[n - i - 1]);
94+
int b = Math.max(nums[i], nums[n - i - 1]);
95+
96+
d[2] += 2;
97+
d[limit * 2 + 1] -= 2;
98+
99+
d[a + 1] -= 1;
100+
d[b + limit + 1] += 1;
101+
102+
d[a + b] -= 1;
103+
d[a + b + 1] += 1;
104+
}
105+
int ans = n, s = 0;
106+
for (int i = 2; i <= limit * 2; ++i) {
107+
s += d[i];
108+
if (ans > s) {
109+
ans = s;
110+
}
111+
}
112+
return ans;
113+
}
114+
}
115+
```
116+
117+
### **C++**
118+
119+
```cpp
120+
class Solution {
121+
public:
122+
int minMoves(vector<int>& nums, int limit) {
123+
int n = nums.size();
124+
vector<int> d(limit * 2 + 2);
125+
for (int i = 0; i < n >> 1; ++i) {
126+
int a = min(nums[i], nums[n - i - 1]);
127+
int b = max(nums[i], nums[n - i - 1]);
128+
129+
d[2] += 2;
130+
d[limit * 2 + 1] -= 2;
131+
132+
d[a + 1] -= 1;
133+
d[b + limit + 1] += 1;
134+
135+
d[a + b] -= 1;
136+
d[a + b + 1] += 1;
137+
}
138+
int ans = n, s = 0;
139+
for (int i = 2; i <= limit * 2; ++i) {
140+
s += d[i];
141+
if (ans > s) {
142+
ans = s;
143+
}
144+
}
145+
return ans;
146+
}
147+
};
148+
```
66149

150+
### **Go**
151+
152+
```go
153+
func minMoves(nums []int, limit int) int {
154+
d := make([]int, limit*2+2)
155+
n := len(nums)
156+
for i := 0; i < n>>1; i++ {
157+
a, b := min(nums[i], nums[n-i-1]), max(nums[i], nums[n-i-1])
158+
d[2] += 2
159+
d[limit*2+1] -= 2
160+
161+
d[a+1] -= 1
162+
d[b+limit+1] += 1
163+
164+
d[a+b] -= 1
165+
d[a+b+1] += 1
166+
}
167+
ans, s := n, 0
168+
for _, v := range d[2 : limit*2+1] {
169+
s += v
170+
if ans > s {
171+
ans = s
172+
}
173+
}
174+
return ans
175+
}
176+
177+
func max(a, b int) int {
178+
if a > b {
179+
return a
180+
}
181+
return b
182+
}
183+
184+
func min(a, b int) int {
185+
if a < b {
186+
return a
187+
}
188+
return b
189+
}
67190
```
68191

69192
### **...**
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
class Solution {
2+
public:
3+
int minMoves(vector<int>& nums, int limit) {
4+
int n = nums.size();
5+
vector<int> d(limit * 2 + 2);
6+
for (int i = 0; i < n >> 1; ++i) {
7+
int a = min(nums[i], nums[n - i - 1]);
8+
int b = max(nums[i], nums[n - i - 1]);
9+
10+
d[2] += 2;
11+
d[limit * 2 + 1] -= 2;
12+
13+
d[a + 1] -= 1;
14+
d[b + limit + 1] += 1;
15+
16+
d[a + b] -= 1;
17+
d[a + b + 1] += 1;
18+
}
19+
int ans = n, s = 0;
20+
for (int i = 2; i <= limit * 2; ++i) {
21+
s += d[i];
22+
if (ans > s) {
23+
ans = s;
24+
}
25+
}
26+
return ans;
27+
}
28+
};
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
func minMoves(nums []int, limit int) int {
2+
d := make([]int, limit*2+2)
3+
n := len(nums)
4+
for i := 0; i < n>>1; i++ {
5+
a, b := min(nums[i], nums[n-i-1]), max(nums[i], nums[n-i-1])
6+
d[2] += 2
7+
d[limit*2+1] -= 2
8+
9+
d[a+1] -= 1
10+
d[b+limit+1] += 1
11+
12+
d[a+b] -= 1
13+
d[a+b+1] += 1
14+
}
15+
ans, s := n, 0
16+
for _, v := range d[2 : limit*2+1] {
17+
s += v
18+
if ans > s {
19+
ans = s
20+
}
21+
}
22+
return ans
23+
}
24+
25+
func max(a, b int) int {
26+
if a > b {
27+
return a
28+
}
29+
return b
30+
}
31+
32+
func min(a, b int) int {
33+
if a < b {
34+
return a
35+
}
36+
return b
37+
}

0 commit comments

Comments
 (0)