57
57
58
58
<!-- 这里可写通用的实现逻辑 -->
59
59
60
+ ** 方法一:数学 + 模拟**
61
+
62
+ 我们设计一个函数 $check(nums, l, r)$,用于判断子数组 $nums[ l] , nums[ l+1] , \dots, nums[ r] $ 是否可以重新排列形成等差数列。
63
+
64
+ 函数 $check(nums, l, r)$ 的实现逻辑如下:
65
+
66
+ - 首先,我们计算子数组的长度 $n = r - l + 1$,并将子数组中的元素放入集合 $s$ 中,方便后续的查找;
67
+ - 然后,我们计算子数组中的最小值 $a_1$ 和最大值 $a_n$,如果 $a_n - a_1$ 不能被 $n - 1$ 整除,那么子数组不可能形成等差数列,直接返回 $false$;否则,我们计算等差数列的公差 $d = \frac{a_n - a_1}{n - 1}$;
68
+ - 接下来从 $a_1$ 开始,依次计算等差数列中第 $i$ 项元素,如果第 $i$ 项元素 $a_1 + (i - 1) \times d$ 不在集合 $s$ 中,那么子数组不可能形成等差数列,直接返回 $false$;否则,当我们遍历完所有的元素,说明子数组可以重新排列形成等差数列,返回 $true$。
69
+
70
+ 在主函数中,我们遍历所有的查询,对于每个查询 $l[ i] $ 和 $r[ i] $,我们调用函数 $check(nums, l[ i] , r[ i] )$ 判断子数组是否可以重新排列形成等差数列,将结果存入答案数组中。
71
+
72
+ 时间复杂度 $O(n \times m)$,空间复杂度 $O(n)$。其中 $n$ 和 $m$ 分别为数组 $nums$ 的长度以及查询的组数。
73
+
60
74
<!-- tabs:start -->
61
75
62
76
### ** Python3**
65
79
66
80
``` python
67
81
class Solution :
68
- def checkArithmeticSubarrays (
69
- self , nums : List[int ], l : List[int ], r : List[int ]
70
- ) -> List[bool ]:
82
+ def checkArithmeticSubarrays (self , nums : List[int ], l : List[int ], r : List[int ]) -> List[bool ]:
71
83
def check (nums , l , r ):
72
- if r - l < 2 :
73
- return True
74
- s = set (nums[l : r + 1 ])
75
- mx = max (nums[l : r + 1 ])
76
- mi = min (nums[l : r + 1 ])
77
- if (mx - mi) % (r - l) != 0 :
78
- return False
79
- delta = (mx - mi) / (r - l)
80
- for i in range (1 , r - l + 1 ):
81
- if (mi + delta * i) not in s:
82
- return False
83
- return True
84
-
85
- return [check(nums, l[i], r[i]) for i in range (len (l))]
84
+ n = r - l + 1
85
+ s = set (nums[l: l + n])
86
+ a1, an = min (nums[l: l + n]), max (nums[l: l + n])
87
+ d, mod = divmod (an - a1, n - 1 )
88
+ return mod == 0 and all ((a1 + (i - 1 ) * d) in s for i in range (1 , n))
89
+
90
+ return [check(nums, left, right) for left, right in zip (l, r)]
86
91
```
87
92
88
93
### ** Java**
@@ -92,31 +97,28 @@ class Solution:
92
97
``` java
93
98
class Solution {
94
99
public List<Boolean > checkArithmeticSubarrays (int [] nums , int [] l , int [] r ) {
95
- List<Boolean > res = new ArrayList<> ();
100
+ List<Boolean > ans = new ArrayList<> ();
96
101
for (int i = 0 ; i < l. length; ++ i) {
97
- res . add(check(nums, l[i], r[i]));
102
+ ans . add(check(nums, l[i], r[i]));
98
103
}
99
- return res ;
104
+ return ans ;
100
105
}
101
106
102
107
private boolean check (int [] nums , int l , int r ) {
103
- if (r - l < 2 ) {
104
- return true ;
105
- }
106
108
Set<Integer > s = new HashSet<> ();
107
- int mx = Integer . MIN_VALUE ;
108
- int mi = Integer . MAX_VALUE ;
109
+ int n = r - l + 1 ;
110
+ int a1 = 1 << 30 , an = - a1 ;
109
111
for (int i = l; i <= r; ++ i) {
110
112
s. add(nums[i]);
111
- mx = Math . max(mx , nums[i]);
112
- mi = Math . min(mi , nums[i]);
113
+ a1 = Math . min(a1 , nums[i]);
114
+ an = Math . max(an , nums[i]);
113
115
}
114
- if ((mx - mi ) % (r - l ) != 0 ) {
116
+ if ((an - a1 ) % (n - 1 ) != 0 ) {
115
117
return false ;
116
118
}
117
- int delta = (mx - mi ) / (r - l );
118
- for (int i = 1 ; i <= r - l ; ++ i) {
119
- if (! s. contains(mi + delta * i )) {
119
+ int d = (an - a1 ) / (n - 1 );
120
+ for (int i = 1 ; i < n ; ++ i) {
121
+ if (! s. contains(a1 + (i - 1 ) * d )) {
120
122
return false ;
121
123
}
122
124
}
@@ -131,80 +133,67 @@ class Solution {
131
133
class Solution {
132
134
public:
133
135
vector<bool > checkArithmeticSubarrays(vector<int >& nums, vector<int >& l, vector<int >& r) {
134
- vector<bool > res;
136
+ vector<bool > ans;
137
+ auto check = [ ] (vector<int >& nums, int l, int r) {
138
+ unordered_set<int > s;
139
+ int n = r - l + 1;
140
+ int a1 = 1 << 30, an = -a1;
141
+ for (int i = l; i <= r; ++i) {
142
+ s.insert(nums[ i] );
143
+ a1 = min(a1, nums[ i] );
144
+ an = max(an, nums[ i] );
145
+ }
146
+ if ((an - a1) % (n - 1)) {
147
+ return false;
148
+ }
149
+ int d = (an - a1) / (n - 1);
150
+ for (int i = 1; i < n; ++i) {
151
+ if (!s.count(a1 + (i - 1) * d)) {
152
+ return false;
153
+ }
154
+ }
155
+ return true;
156
+ };
135
157
for (int i = 0; i < l.size(); ++i) {
136
- res.push_back(check(nums, l[ i] , r[ i] ));
137
- }
138
- return res;
139
- }
140
-
141
- bool check(vector<int>& nums, int l, int r) {
142
- if (r - l < 2) return true;
143
- unordered_set<int> s;
144
- int mx = -100010;
145
- int mi = 100010;
146
- for (int i = l; i <= r; ++i) {
147
- s.insert(nums[i]);
148
- mx = max(mx, nums[i]);
149
- mi = min(mi, nums[i]);
150
- }
151
- if ((mx - mi) % (r - l) != 0 ) return false ;
152
- int delta = (mx - mi) / (r - l);
153
- for (int i = 1 ; i <= r - l; ++i) {
154
- if (!s.count(mi + delta * i)) return false;
158
+ ans.push_back(check(nums, l[ i] , r[ i] ));
155
159
}
156
- return true ;
160
+ return ans ;
157
161
}
158
162
};
159
163
```
160
164
161
165
### **Go**
162
166
163
167
```go
164
- func checkArithmeticSubarrays (nums []int , l []int , r []int ) []bool {
165
- n := len (l)
166
- var res []bool
167
- for i := 0 ; i < n; i++ {
168
- res = append (res, check (nums, l[i], r[i]))
169
- }
170
- return res
171
- }
172
-
173
- func check (nums []int , l , r int ) bool {
174
- if r-l < 2 {
175
- return true
176
- }
177
- s := make (map [int ]bool )
178
- mx , mi := -100010 , 100010
179
- for i := l; i <= r; i++ {
180
- s[nums[i]] = true
181
- mx = max (mx, nums[i])
182
- mi = min (mi, nums[i])
183
- }
184
- if (mx-mi)%(r-l) != 0 {
185
- return false
186
- }
187
- delta := (mx - mi) / (r - l)
188
- for i := 1 ; i <= r-l; i++ {
189
- if !s[mi+delta*i] {
168
+ func checkArithmeticSubarrays(nums []int, l []int, r []int) (ans []bool) {
169
+ check := func(nums []int, l, r int) bool {
170
+ s := map[int]struct{}{}
171
+ n := r - l + 1
172
+ a1, an := 1<<30, -(1 << 30)
173
+ for _, x := range nums[l : r+1] {
174
+ s[x] = struct{}{}
175
+ if a1 > x {
176
+ a1 = x
177
+ }
178
+ if an < x {
179
+ an = x
180
+ }
181
+ }
182
+ if (an-a1)%(n-1) != 0 {
190
183
return false
191
184
}
185
+ d := (an - a1) / (n - 1)
186
+ for i := 1; i < n; i++ {
187
+ if _, ok := s[a1+(i-1)*d]; !ok {
188
+ return false
189
+ }
190
+ }
191
+ return true
192
192
}
193
- return true
194
- }
195
-
196
- func max (a , b int ) int {
197
- if a > b {
198
- return a
199
- }
200
- return b
201
- }
202
-
203
- func min (a , b int ) int {
204
- if a < b {
205
- return a
193
+ for i := range l {
194
+ ans = append(ans, check(nums, l[i], r[i]))
206
195
}
207
- return b
196
+ return
208
197
}
209
198
```
210
199
@@ -216,18 +205,32 @@ function checkArithmeticSubarrays(
216
205
l : number [],
217
206
r : number [],
218
207
): boolean [] {
219
- const m = l .length ;
220
- const res = new Array (m ).fill (true );
221
- for (let i = 0 ; i < m ; i ++ ) {
222
- const arr = nums .slice (l [i ], r [i ] + 1 ).sort ((a , b ) => b - a );
223
- for (let j = 2 ; j < arr .length ; j ++ ) {
224
- if (arr [j - 2 ] - arr [j - 1 ] !== arr [j - 1 ] - arr [j ]) {
225
- res [i ] = false ;
226
- break ;
208
+ const check = (nums : number [], l : number , r : number ): boolean => {
209
+ const s = new Set <number >();
210
+ const n = r - l + 1 ;
211
+ let a1 = 1 << 30 ;
212
+ let an = - a1 ;
213
+ for (let i = l ; i <= r ; ++ i ) {
214
+ s .add (nums [i ]);
215
+ a1 = Math .min (a1 , nums [i ]);
216
+ an = Math .max (an , nums [i ]);
217
+ }
218
+ if ((an - a1 ) % (n - 1 ) !== 0 ) {
219
+ return false ;
220
+ }
221
+ const d = Math .floor ((an - a1 ) / (n - 1 ));
222
+ for (let i = 1 ; i < n ; ++ i ) {
223
+ if (! s .has (a1 + (i - 1 ) * d )) {
224
+ return false ;
227
225
}
228
226
}
227
+ return true ;
228
+ };
229
+ const ans: boolean [] = [];
230
+ for (let i = 0 ; i < l .length ; ++ i ) {
231
+ ans .push (check (nums , l [i ], r [i ]));
229
232
}
230
- return res ;
233
+ return ans ;
231
234
}
232
235
```
233
236
0 commit comments