Skip to content

Commit 1143a96

Browse files
authored
feat: add solutions to lc problem: No.1438 (#2575)
No.1438.Longest Continuous Subarray With Absolute Diff Less Than or Equal to Limit
1 parent 2c6cd87 commit 1143a96

File tree

11 files changed

+1128
-87
lines changed

11 files changed

+1128
-87
lines changed

solution/1400-1499/1438.Longest Continuous Subarray With Absolute Diff Less Than or Equal to Limit/README.md

+385-29
Large diffs are not rendered by default.

solution/1400-1499/1438.Longest Continuous Subarray With Absolute Diff Less Than or Equal to Limit/README_EN.md

+385-29
Large diffs are not rendered by default.

solution/1400-1499/1438.Longest Continuous Subarray With Absolute Diff Less Than or Equal to Limit/Solution.go

+12-19
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,18 @@
11
func longestSubarray(nums []int, limit int) (ans int) {
2-
tm := treemap.NewWithIntComparator()
3-
j := 0
4-
for i, v := range nums {
5-
if x, ok := tm.Get(v); ok {
6-
tm.Put(v, x.(int)+1)
2+
merge := func(st *redblacktree.Tree[int, int], x, v int) {
3+
c, _ := st.Get(x)
4+
if c+v == 0 {
5+
st.Remove(x)
76
} else {
8-
tm.Put(v, 1)
7+
st.Put(x, c+v)
98
}
10-
for {
11-
a, _ := tm.Min()
12-
b, _ := tm.Max()
13-
if b.(int)-a.(int) > limit {
14-
if x, _ := tm.Get(nums[j]); x.(int) == 1 {
15-
tm.Remove(nums[j])
16-
} else {
17-
tm.Put(nums[j], x.(int)-1)
18-
}
19-
j++
20-
} else {
21-
break
22-
}
9+
}
10+
st := redblacktree.New[int, int]()
11+
j := 0
12+
for i, x := range nums {
13+
merge(st, x, 1)
14+
for ; st.Right().Key-st.Left().Key > limit; j++ {
15+
merge(st, nums[j], -1)
2316
}
2417
ans = max(ans, i-j+1)
2518
}

solution/1400-1499/1438.Longest Continuous Subarray With Absolute Diff Less Than or Equal to Limit/Solution.java

+5-7
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
class Solution {
22
public int longestSubarray(int[] nums, int limit) {
33
TreeMap<Integer, Integer> tm = new TreeMap<>();
4-
int ans = 0, j = 0;
5-
for (int i = 0; i < nums.length; ++i) {
6-
tm.put(nums[i], tm.getOrDefault(nums[i], 0) + 1);
7-
while (tm.lastKey() - tm.firstKey() > limit) {
8-
tm.put(nums[j], tm.get(nums[j]) - 1);
9-
if (tm.get(nums[j]) == 0) {
4+
int ans = 0;
5+
for (int i = 0, j = 0; i < nums.length; ++i) {
6+
tm.merge(nums[i], 1, Integer::sum);
7+
for (; tm.lastKey() - tm.firstKey() > limit; ++j) {
8+
if (tm.merge(nums[j], -1, Integer::sum) == 0) {
109
tm.remove(nums[j]);
1110
}
12-
++j;
1311
}
1412
ans = Math.max(ans, i - j + 1);
1513
}

solution/1400-1499/1438.Longest Continuous Subarray With Absolute Diff Less Than or Equal to Limit/Solution.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ class Solution:
55
def longestSubarray(self, nums: List[int], limit: int) -> int:
66
sl = SortedList()
77
ans = j = 0
8-
for i, v in enumerate(nums):
9-
sl.add(v)
8+
for i, x in enumerate(nums):
9+
sl.add(x)
1010
while sl[-1] - sl[0] > limit:
1111
sl.remove(nums[j])
1212
j += 1

solution/1400-1499/1438.Longest Continuous Subarray With Absolute Diff Less Than or Equal to Limit/Solution.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ function longestSubarray(nums: number[], limit: number): number {
44
let j = 0;
55
for (let i = 0; i < nums.length; ++i) {
66
ts.add(nums[i]);
7-
while (ts.last() - ts.first() > limit) {
7+
while (ts.last()! - ts.first()! > limit) {
88
ts.delete(nums[j++]);
99
}
1010
ans = Math.max(ans, i - j + 1);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
class Solution {
2+
public:
3+
int longestSubarray(vector<int>& nums, int limit) {
4+
auto check = [&](int k) {
5+
deque<int> min_q;
6+
deque<int> max_q;
7+
for (int i = 0; i < nums.size(); ++i) {
8+
if (!min_q.empty() && i - min_q.front() + 1 > k) {
9+
min_q.pop_front();
10+
}
11+
if (!max_q.empty() && i - max_q.front() + 1 > k) {
12+
max_q.pop_front();
13+
}
14+
while (!min_q.empty() && nums[min_q.back()] >= nums[i]) {
15+
min_q.pop_back();
16+
}
17+
while (!max_q.empty() && nums[max_q.back()] <= nums[i]) {
18+
max_q.pop_back();
19+
}
20+
min_q.push_back(i);
21+
max_q.push_back(i);
22+
if (i >= k - 1 && nums[max_q.front()] - nums[min_q.front()] <= limit) {
23+
return true;
24+
}
25+
}
26+
return false;
27+
};
28+
int l = 1, r = nums.size();
29+
while (l < r) {
30+
int mid = (l + r + 1) >> 1;
31+
if (check(mid)) {
32+
l = mid;
33+
} else {
34+
r = mid - 1;
35+
}
36+
}
37+
return l;
38+
}
39+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
func longestSubarray(nums []int, limit int) int {
2+
l, r := 0, len(nums)
3+
check := func(k int) bool {
4+
minq := Deque{}
5+
maxq := Deque{}
6+
for i, x := range nums {
7+
for !minq.Empty() && i-minq.Front()+1 > k {
8+
minq.PopFront()
9+
}
10+
for !maxq.Empty() && i-maxq.Front()+1 > k {
11+
maxq.PopFront()
12+
}
13+
for !minq.Empty() && nums[minq.Back()] >= x {
14+
minq.PopBack()
15+
}
16+
for !maxq.Empty() && nums[maxq.Back()] <= x {
17+
maxq.PopBack()
18+
}
19+
minq.PushBack(i)
20+
maxq.PushBack(i)
21+
if i >= k-1 && nums[maxq.Front()]-nums[minq.Front()] <= limit {
22+
return true
23+
}
24+
}
25+
return false
26+
}
27+
for l < r {
28+
mid := (l + r + 1) >> 1
29+
if check(mid) {
30+
l = mid
31+
} else {
32+
r = mid - 1
33+
}
34+
}
35+
return l
36+
}
37+
38+
// template
39+
type Deque struct{ l, r []int }
40+
41+
func (q Deque) Empty() bool {
42+
return len(q.l) == 0 && len(q.r) == 0
43+
}
44+
45+
func (q Deque) Size() int {
46+
return len(q.l) + len(q.r)
47+
}
48+
49+
func (q *Deque) PushFront(v int) {
50+
q.l = append(q.l, v)
51+
}
52+
53+
func (q *Deque) PushBack(v int) {
54+
q.r = append(q.r, v)
55+
}
56+
57+
func (q *Deque) PopFront() (v int) {
58+
if len(q.l) > 0 {
59+
q.l, v = q.l[:len(q.l)-1], q.l[len(q.l)-1]
60+
} else {
61+
v, q.r = q.r[0], q.r[1:]
62+
}
63+
return
64+
}
65+
66+
func (q *Deque) PopBack() (v int) {
67+
if len(q.r) > 0 {
68+
q.r, v = q.r[:len(q.r)-1], q.r[len(q.r)-1]
69+
} else {
70+
v, q.l = q.l[0], q.l[1:]
71+
}
72+
return
73+
}
74+
75+
func (q Deque) Front() int {
76+
if len(q.l) > 0 {
77+
return q.l[len(q.l)-1]
78+
}
79+
return q.r[0]
80+
}
81+
82+
func (q Deque) Back() int {
83+
if len(q.r) > 0 {
84+
return q.r[len(q.r)-1]
85+
}
86+
return q.l[0]
87+
}
88+
89+
func (q Deque) Get(i int) int {
90+
if i < len(q.l) {
91+
return q.l[len(q.l)-1-i]
92+
}
93+
return q.r[i-len(q.l)]
94+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
class Solution {
2+
private int[] nums;
3+
private int limit;
4+
5+
public int longestSubarray(int[] nums, int limit) {
6+
this.nums = nums;
7+
this.limit = limit;
8+
int l = 1, r = nums.length;
9+
while (l < r) {
10+
int mid = (l + r + 1) >> 1;
11+
if (check(mid)) {
12+
l = mid;
13+
} else {
14+
r = mid - 1;
15+
}
16+
}
17+
return l;
18+
}
19+
20+
private boolean check(int k) {
21+
Deque<Integer> minQ = new ArrayDeque<>();
22+
Deque<Integer> maxQ = new ArrayDeque<>();
23+
for (int i = 0; i < nums.length; ++i) {
24+
if (!minQ.isEmpty() && i - minQ.peekFirst() + 1 > k) {
25+
minQ.pollFirst();
26+
}
27+
if (!maxQ.isEmpty() && i - maxQ.peekFirst() + 1 > k) {
28+
maxQ.pollFirst();
29+
}
30+
while (!minQ.isEmpty() && nums[minQ.peekLast()] >= nums[i]) {
31+
minQ.pollLast();
32+
}
33+
while (!maxQ.isEmpty() && nums[maxQ.peekLast()] <= nums[i]) {
34+
maxQ.pollLast();
35+
}
36+
minQ.offer(i);
37+
maxQ.offer(i);
38+
if (i >= k - 1 && nums[maxQ.peekFirst()] - nums[minQ.peekFirst()] <= limit) {
39+
return true;
40+
}
41+
}
42+
return false;
43+
}
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
class Solution:
2+
def longestSubarray(self, nums: List[int], limit: int) -> int:
3+
def check(k: int) -> bool:
4+
min_q = deque()
5+
max_q = deque()
6+
for i, x in enumerate(nums):
7+
if min_q and i - min_q[0] + 1 > k:
8+
min_q.popleft()
9+
if max_q and i - max_q[0] + 1 > k:
10+
max_q.popleft()
11+
while min_q and nums[min_q[-1]] >= x:
12+
min_q.pop()
13+
while max_q and nums[max_q[-1]] <= x:
14+
max_q.pop()
15+
min_q.append(i)
16+
max_q.append(i)
17+
if i >= k - 1 and nums[max_q[0]] - nums[min_q[0]] <= limit:
18+
return True
19+
return False
20+
21+
l, r = 1, len(nums)
22+
while l < r:
23+
mid = (l + r + 1) >> 1
24+
if check(mid):
25+
l = mid
26+
else:
27+
r = mid - 1
28+
return l

0 commit comments

Comments
 (0)