Skip to content

feat: update 2nd and add 3rd ts solution to lc problem: No.1438 #3160

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Jun 25, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -1050,136 +1050,167 @@ func (q Deque) Get(i int) int {

```ts
function longestSubarray(nums: number[], limit: number): number {
const n = nums.length;
let [l, r] = [0, n];
const check = (k: number): boolean => {
const minq = new Deque<number>();
const maxq = new Deque<number>();
for (let i = 0; i < n; ++i) {
while (!minq.isEmpty() && i - minq.frontValue()! + 1 > k) {
minq.popFront();
}
while (!maxq.isEmpty() && i - maxq.frontValue()! + 1 > k) {
maxq.popFront();
}
while (!minq.isEmpty() && nums[minq.backValue()!] >= nums[i]) {
minq.popBack();
}
while (!maxq.isEmpty() && nums[maxq.backValue()!] <= nums[i]) {
maxq.popBack();
}
minq.pushBack(i);
maxq.pushBack(i);
if (i >= k - 1 && nums[maxq.frontValue()!] - nums[minq.frontValue()!] <= limit) {
return true;
}
}
return false;
};
while (l < r) {
const mid = (l + r + 1) >> 1;
if (check(mid)) {
l = mid;
let ans = 0;
let l = 0;
const maxQueue: number[] = [];
const minQueue: number[] = [];

for (let r = 0; r < nums.length; r++) {
while (maxQueue.length && nums[maxQueue.at(-1)!] < nums[r]) maxQueue.pop();
while (minQueue.length && nums[minQueue.at(-1)!] > nums[r]) minQueue.pop();
maxQueue.push(r);
minQueue.push(r);

const diff = nums[maxQueue[0]] - nums[minQueue[0]];

if (diff <= limit) {
ans = Math.max(ans, r - l + 1);
} else {
r = mid - 1;
l++;

if (maxQueue[0] < l) maxQueue.shift();
if (minQueue[0] < l) minQueue.shift();
}
}
return l;

return ans;
}
```

class Node<T> {
value: T;
next: Node<T> | null;
prev: Node<T> | null;
<!-- tabs:end -->

constructor(value: T) {
this.value = value;
this.next = null;
this.prev = null;
<!-- solution:end -->

<!-- solution:start -->

### Solution 3. Min-max heaps

<!-- tabs:start -->

#### TypeScript

```ts
function longestSubarray(nums: number[], limit: number): number {
let [ans, l, r, n] = [0, 0, 0, nums.length];

const minHeap = new MinHeap();
const maxHeap = new MaxHeap();

minHeap.push(nums[r]);
maxHeap.push(nums[r]);

while (r < n) {
const diff = maxHeap.peek()! - minHeap.peek()!;

if (diff <= limit) {
ans = Math.max(ans, minHeap.size);
r++;
if (r < n) {
minHeap.push(nums[r]);
maxHeap.push(nums[r]);
}
} else {
minHeap.remove(nums[l]);
maxHeap.remove(nums[l]);
l++;
}
}

return ans;
}

class Deque<T> {
private front: Node<T> | null;
private back: Node<T> | null;
private size: number;
class MinHeap<T = number> {
#h: T[] = [];

constructor() {
this.front = null;
this.back = null;
this.size = 0;
get size() {
return this.#h.length;
}

pushFront(val: T): void {
const newNode = new Node(val);
if (this.isEmpty()) {
this.front = newNode;
this.back = newNode;
} else {
newNode.next = this.front;
this.front!.prev = newNode;
this.front = newNode;
push(x: T) {
const h = this.#h;

h.push(x);
if (h.length === 1) return;

let i = h.length - 1;
while (i !== undefined) {
const p = i >> 1;
if (h[p] <= h[i]) return;
this.#swap(i, p);
i = p;
}
this.size++;
}

pushBack(val: T): void {
const newNode = new Node(val);
if (this.isEmpty()) {
this.front = newNode;
this.back = newNode;
} else {
newNode.prev = this.back;
this.back!.next = newNode;
this.back = newNode;
}
this.size++;
pop(): T | undefined {
return this.#sinkingDown();
}

popFront(): T | undefined {
if (this.isEmpty()) {
return undefined;
}
const value = this.front!.value;
this.front = this.front!.next;
if (this.front !== null) {
this.front.prev = null;
} else {
this.back = null;
}
this.size--;
return value;
remove(v: T) {
const i = this.#h.indexOf(v);
if (i === -1) return;
this.#sinkingDown(i);
}

peek(): T | undefined {
return this.#h[0];
}

popBack(): T | undefined {
if (this.isEmpty()) {
return undefined;
#sinkingDown(i = 0): T | undefined {
const h = this.#h;

if (h.length <= 2) {
const val = this.#h.splice(i, 1)[0];
return val;
}
const value = this.back!.value;
this.back = this.back!.prev;
if (this.back !== null) {
this.back.next = null;
} else {
this.front = null;

this.#swap(i, h.length - 1);
const val = h.pop();

while (true) {
const l = 2 * i + 1;
const r = 2 * i + 2;
const child = h[l] && h[r] ? (h[l] <= h[r] ? l : r) : h[l] ? l : r;

if (!h[child] || h[i] <= h[child]) break;

this.#swap(i, child);
i = child;
}
this.size--;
return value;

return val;
}

#swap(i: number, j: number) {
const h = this.#h;
[h[i], h[j]] = [h[j], h[i]];
}

frontValue(): T | undefined {
return this.front?.value;
*[Symbol.iterator]() {
const h = [...this.#h];
while (this.#h.length) yield this.pop();
this.#h = h;
}
}

export class MaxHeap extends MinHeap {
push(x: number): void {
super.push(-x);
}

backValue(): T | undefined {
return this.back?.value;
pop(): number | undefined {
const res = super.pop();
if (res === undefined) return;
return -res;
}

getSize(): number {
return this.size;
peek(): number | undefined {
const res = super.peek();
if (res === undefined) return;
return -res;
}

isEmpty(): boolean {
return this.size === 0;
remove(v: number): void {
super.remove(-v);
}
}
```
Expand Down
Loading
Loading