Skip to content

Commit 4d43f5e

Browse files
committed
feat: add solutions to lc problem: No.1630
No.1630.Arithmetic Subarrays
1 parent 57393fc commit 4d43f5e

File tree

7 files changed

+282
-299
lines changed

7 files changed

+282
-299
lines changed

solution/1600-1699/1630.Arithmetic Subarrays/README.md

+104-101
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,20 @@
5757

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

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+
6074
<!-- tabs:start -->
6175

6276
### **Python3**
@@ -65,24 +79,15 @@
6579

6680
```python
6781
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]:
7183
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)]
8691
```
8792

8893
### **Java**
@@ -92,31 +97,28 @@ class Solution:
9297
```java
9398
class Solution {
9499
public List<Boolean> checkArithmeticSubarrays(int[] nums, int[] l, int[] r) {
95-
List<Boolean> res = new ArrayList<>();
100+
List<Boolean> ans = new ArrayList<>();
96101
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]));
98103
}
99-
return res;
104+
return ans;
100105
}
101106

102107
private boolean check(int[] nums, int l, int r) {
103-
if (r - l < 2) {
104-
return true;
105-
}
106108
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;
109111
for (int i = l; i <= r; ++i) {
110112
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]);
113115
}
114-
if ((mx - mi) % (r - l) != 0) {
116+
if ((an - a1) % (n - 1) != 0) {
115117
return false;
116118
}
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)) {
120122
return false;
121123
}
122124
}
@@ -131,80 +133,67 @@ class Solution {
131133
class Solution {
132134
public:
133135
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+
};
135157
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]));
155159
}
156-
return true;
160+
return ans;
157161
}
158162
};
159163
```
160164
161165
### **Go**
162166
163167
```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 {
190183
return false
191184
}
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
192192
}
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]))
206195
}
207-
return b
196+
return
208197
}
209198
```
210199

@@ -216,18 +205,32 @@ function checkArithmeticSubarrays(
216205
l: number[],
217206
r: number[],
218207
): 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;
227225
}
228226
}
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]));
229232
}
230-
return res;
233+
return ans;
231234
}
232235
```
233236

0 commit comments

Comments
 (0)