Skip to content

Commit 0bc3f2e

Browse files
committed
new soln
1 parent 30bfa8e commit 0bc3f2e

File tree

3 files changed

+296
-0
lines changed

3 files changed

+296
-0
lines changed

1438.LongestSubarray.cs

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// 1438. Longest Continuous Subarray With Absolute Diff Less Than or Equal to Limit
2+
3+
// Given an array of integers nums and an integer limit, return the size of the longest non-empty subarray such that the absolute difference between any two elements of this subarray is less than or equal to limit.
4+
5+
// Example 1:
6+
// Input: nums = [8,2,4,7], limit = 4
7+
// Output: 2
8+
// Explanation: All subarrays are:
9+
// [8] with maximum absolute diff |8-8| = 0 <= 4.
10+
// [8,2] with maximum absolute diff |8-2| = 6 > 4.
11+
// [8,2,4] with maximum absolute diff |8-2| = 6 > 4.
12+
// [8,2,4,7] with maximum absolute diff |8-2| = 6 > 4.
13+
// [2] with maximum absolute diff |2-2| = 0 <= 4.
14+
// [2,4] with maximum absolute diff |2-4| = 2 <= 4.
15+
// [2,4,7] with maximum absolute diff |2-7| = 5 > 4.
16+
// [4] with maximum absolute diff |4-4| = 0 <= 4.
17+
// [4,7] with maximum absolute diff |4-7| = 3 <= 4.
18+
// [7] with maximum absolute diff |7-7| = 0 <= 4.
19+
// Therefore, the size of the longest subarray is 2.
20+
// Example 2:
21+
// Input: nums = [10,1,2,4,7,2], limit = 5
22+
// Output: 4
23+
// Explanation: The subarray [2,4,7,2] is the longest since the maximum absolute diff is |2-7| = 5 <= 5.
24+
// Example 3:
25+
// Input: nums = [4,2,2,2,4,4,2,2], limit = 0
26+
// Output: 3
27+
28+
// Constraints:
29+
// 1 <= nums.length <= 105
30+
// 1 <= nums[i] <= 109
31+
// 0 <= limit <= 109
32+
33+
public class Solution {
34+
public int LongestSubarray(int[] nums, int limit) {
35+
int start = 0;
36+
int maxLength = 0;
37+
38+
LinkedList<int> minDeque = new LinkedList<int>();
39+
LinkedList<int> maxDeque = new LinkedList<int>();
40+
41+
for (int end = 0; end < nums.Length; end++) {
42+
// Maintain the maxDeque: elements in decreasing order
43+
while (maxDeque.Count > 0 && maxDeque.Last.Value < nums[end]) {
44+
maxDeque.RemoveLast();
45+
}
46+
maxDeque.AddLast(nums[end]);
47+
48+
// Maintain the minDeque: elements in increasing order
49+
while (minDeque.Count > 0 && minDeque.Last.Value > nums[end]) {
50+
minDeque.RemoveLast();
51+
}
52+
minDeque.AddLast(nums[end]);
53+
54+
// Check if the current window is valid
55+
while (maxDeque.First.Value - minDeque.First.Value > limit) {
56+
if (maxDeque.First.Value == nums[start]) {
57+
maxDeque.RemoveFirst();
58+
}
59+
if (minDeque.First.Value == nums[start]) {
60+
minDeque.RemoveFirst();
61+
}
62+
start++;
63+
}
64+
65+
// Update the maximum length
66+
maxLength = Math.Max(maxLength, end - start + 1);
67+
}
68+
69+
return maxLength;
70+
}
71+
}
72+
73+
// LinkedList for Deques:
74+
// We use LinkedList<int> directly to maintain the minimum and maximum values.
75+
// These linked lists (minDeque and maxDeque) will store values in a way that allows efficient addition and removal from both ends.
76+
77+
// Maintaining Deques:
78+
// For maxDeque, we remove elements from the back while the current element is greater than the elements at the back to maintain a decreasing order.
79+
// For minDeque, we remove elements from the back while the current element is less than the elements at the back to maintain an increasing order.
80+
81+
// Validating the Window:
82+
// If the difference between the maximum and minimum values in the current window exceeds the limit, we shrink the window from the start.
83+
// This involves removing the element at the start from the deques if it is the front element of either deque.
84+
85+
// Max Length Calculation:
86+
// We update maxLength with the size of the current valid window.
87+
88+
// Complexity:
89+
// Time Complexity: O(n), where n is the length of the array. Each element is added and removed from the deques at most once.
90+
// Space Complexity: O(n) in the worst case, for the deques.

2302.CountSubarrays.cs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// 2302. Count Subarrays With Score Less Than K
2+
// The score of an array is defined as the product of its sum and its length.
3+
// For example, the score of [1, 2, 3, 4, 5] is (1 + 2 + 3 + 4 + 5) * 5 = 75.
4+
// Given a positive integer array nums and an integer k, return the number of non-empty subarrays of nums whose score is strictly less than k.
5+
// A subarray is a contiguous sequence of elements within an array.
6+
7+
// Example 1:
8+
// Input: nums = [2,1,4,3,5], k = 10
9+
// Output: 6
10+
// Explanation:
11+
// The 6 subarrays having scores less than 10 are:
12+
// - [2] with score 2 * 1 = 2.
13+
// - [1] with score 1 * 1 = 1.
14+
// - [4] with score 4 * 1 = 4.
15+
// - [3] with score 3 * 1 = 3.
16+
// - [5] with score 5 * 1 = 5.
17+
// - [2,1] with score (2 + 1) * 2 = 6.
18+
// Note that subarrays such as [1,4] and [4,3,5] are not considered because their scores are 10 and 36 respectively, while we need scores strictly less than 10.
19+
20+
// Example 2:
21+
// Input: nums = [1,1,1], k = 5
22+
// Output: 5
23+
// Explanation:
24+
// Every subarray except [1,1,1] has a score less than 5.
25+
// [1,1,1] has a score (1 + 1 + 1) * 3 = 9, which is greater than 5.
26+
// Thus, there are 5 subarrays having scores less than 5.
27+
28+
// Constraints:
29+
// 1 <= nums.length <= 105
30+
// 1 <= nums[i] <= 105
31+
// 1 <= k <= 1015
32+
33+
public class Solution {
34+
public long CountSubarrays(int[] nums, long k) {
35+
// n is the length of the input array
36+
int n = nums.Length;
37+
// Variable to keep track of the count of subarrays
38+
long count = 0;
39+
// Variable to keep the current sum of the window
40+
long currentSum = 0;
41+
// Start pointer for the sliding window
42+
int start = 0;
43+
44+
// Iterate through each element in the array with the end pointer
45+
for (int end = 0; end < n; end++) {
46+
// Add the current element to the currentSum
47+
currentSum += nums[end];
48+
49+
// While the score of the current window is not less than k
50+
while (currentSum * (end - start + 1) >= k) {
51+
// Remove the start element from the currentSum and move the start pointer to the right
52+
currentSum -= nums[start];
53+
start++;
54+
}
55+
56+
// Add the number of valid subarrays ending at the current end pointer
57+
count += (end - start + 1);
58+
}
59+
60+
// Return the total count of valid subarrays
61+
return count;
62+
}
63+
}
64+
65+
/*
66+
Complexity Analysis:
67+
- Time Complexity: O(n)
68+
Each element is added and removed from the currentSum at most once, resulting in a linear time complexity.
69+
- Space Complexity: O(1)
70+
We use a few extra variables (currentSum, count, start) that do not depend on the input size, resulting in constant space complexity.
71+
72+
73+
Sliding Window Approach:
74+
We use a sliding window to keep track of the current subarray sum.
75+
The start pointer moves right whenever the score condition currentSum * (end - start + 1) >= k is not met.
76+
77+
Efficiency:
78+
The sliding window ensures that each element is processed in linear time, improving efficiency from the original nested loop approach.
79+
80+
Loop Indices:
81+
Using int for indices since array indices are integers.
82+
83+
*/

MinHeap.cs

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
using System;
2+
3+
public class MinHeap
4+
{
5+
private int[] heap;
6+
private int size;
7+
private int capacity;
8+
9+
public MinHeap(int capacity)
10+
{
11+
this.capacity = capacity;
12+
this.size = 0;
13+
this.heap = new int[capacity];
14+
}
15+
16+
private int GetLeftChildIndex(int index) => 2 * index + 1;
17+
private int GetRightChildIndex(int index) => 2 * index + 2;
18+
private int GetParentIndex(int index) => (index - 1) / 2;
19+
20+
private bool HasLeftChild(int index) => GetLeftChildIndex(index) < size;
21+
private bool HasRightChild(int index) => GetRightChildIndex(index) < size;
22+
private bool HasParent(int index) => GetParentIndex(index) >= 0;
23+
24+
private int LeftChild(int index) => heap[GetLeftChildIndex(index)];
25+
private int RightChild(int index) => heap[GetRightChildIndex(index)];
26+
private int Parent(int index) => heap[GetParentIndex(index)];
27+
28+
private void Swap(int indexOne, int indexTwo)
29+
{
30+
int temp = heap[indexOne];
31+
heap[indexOne] = heap[indexTwo];
32+
heap[indexTwo] = temp;
33+
}
34+
35+
public int Peek()
36+
{
37+
if (size == 0) throw new InvalidOperationException("Heap is empty");
38+
return heap[0];
39+
}
40+
41+
public void Enqueue(int item)
42+
{
43+
EnsureExtraCapacity();
44+
heap[size] = item;
45+
size++;
46+
HeapifyUp();
47+
}
48+
49+
public int Dequeue()
50+
{
51+
if (size == 0) throw new InvalidOperationException("Heap is empty");
52+
int item = heap[0];
53+
heap[0] = heap[size - 1];
54+
size--;
55+
HeapifyDown();
56+
return item;
57+
}
58+
59+
private void EnsureExtraCapacity()
60+
{
61+
if (size == capacity)
62+
{
63+
Array.Resize(ref heap, capacity * 2);
64+
capacity *= 2;
65+
}
66+
}
67+
68+
private void HeapifyUp()
69+
{
70+
int index = size - 1;
71+
while (HasParent(index) && Parent(index) > heap[index])
72+
{
73+
Swap(GetParentIndex(index), index);
74+
index = GetParentIndex(index);
75+
}
76+
}
77+
78+
private void HeapifyDown()
79+
{
80+
int index = 0;
81+
while (HasLeftChild(index))
82+
{
83+
int smallerChildIndex = GetLeftChildIndex(index);
84+
if (HasRightChild(index) && RightChild(index) < LeftChild(index))
85+
{
86+
smallerChildIndex = GetRightChildIndex(index);
87+
}
88+
89+
if (heap[index] < heap[smallerChildIndex])
90+
{
91+
break;
92+
}
93+
else
94+
{
95+
Swap(index, smallerChildIndex);
96+
}
97+
98+
index = smallerChildIndex;
99+
}
100+
}
101+
}
102+
103+
// Example usage:
104+
public class Program
105+
{
106+
public static void Main(string[] args)
107+
{
108+
MinHeap minHeap = new MinHeap(10);
109+
minHeap.Enqueue(5);
110+
minHeap.Enqueue(3);
111+
minHeap.Enqueue(8);
112+
minHeap.Enqueue(1);
113+
114+
Console.WriteLine(minHeap.Peek()); // Output: 1
115+
116+
Console.WriteLine(minHeap.Dequeue()); // Output: 1
117+
Console.WriteLine(minHeap.Dequeue()); // Output: 3
118+
119+
minHeap.Enqueue(2);
120+
121+
Console.WriteLine(minHeap.Peek()); // Output: 2
122+
}
123+
}

0 commit comments

Comments
 (0)