Initialize window_start = 0
Initialize window_sum = 0
Initialize max_sum = -∞
For window_end in 0 to n-1:
window_sum += arr[window_end]
If window size > k:
window_sum -= arr[window_start]
window_start += 1
Update max_sum
Return max_sumWhen to use
- Fixed/variable size contiguous subarray
- Maximum/minimum sum window
Time: O(n)
public int maxSubarraySumK(int[] arr, int k) {
int windowStart = 0;
int windowSum = 0;
int maxSum = Integer.MIN_VALUE;
for (int windowEnd = 0; windowEnd < arr.length; windowEnd++) {
windowSum += arr[windowEnd];
if (windowEnd >= k - 1) {
maxSum = Math.max(maxSum, windowSum);
windowSum -= arr[windowStart];
windowStart++;
}
}
return maxSum;
}2 Two Pointers
Sort array
left = 0
right = n-1
While left < right:
sum = arr[left] + arr[right]
If sum == target:
return solution
Else if sum < target:
left++
Else:
right--When to use
- Pair/triplet sum
- Sorted arrays
Time: O(n) after sorting
public int[] twoSumSorted(int[] arr, int target) {
int left = 0;
int right = arr.length - 1;
while (left < right) {
int sum = arr[left] + arr[right];
if (sum == target) {
return new int[]{left, right};
} else if (sum < target) {
left++;
} else {
right--;
}
}
return new int[]{-1, -1};
}3 Prefix Sum
prefix[0] = arr[0]
For i in 1 to n-1:
prefix[i] = prefix[i-1] + arr[i]
To get sum(i..j):
If i == 0:
return prefix[j]
Else:
return prefix[j] - prefix[i-1]When to use
- Range sum queries
- Repeated subarray queries
Time: O(n) build, O(1) query
public int[] buildPrefixSum(int[] arr) {
int n = arr.length;
int[] prefix = new int[n];
prefix[0] = arr[0];
for (int i = 1; i < n; i++) {
prefix[i] = prefix[i - 1] + arr[i];
}
return prefix;
}
public int rangeSum(int[] prefix, int i, int j) {
if (i == 0) return prefix[j];
return prefix[j] - prefix[i - 1];
}4 Kadane’s Algorithm
max_sum = arr[0]
current_sum = 0
For num in arr:
current_sum += num
max_sum = max(max_sum, current_sum)
If current_sum < 0:
current_sum = 0
Return max_sumWhen to use
- Maximum sum contiguous subarray
Time: O(n)
Handle all-negative arrays properly.
public int maxSubArray(int[] nums) {
int maxSum = nums[0];
int currentSum = 0;
for (int num : nums) {
currentSum += num;
maxSum = Math.max(maxSum, currentSum);
if (currentSum < 0) {
currentSum = 0;
}
}
return maxSum;
}5 Dutch National Flag (Partition)
low = 0
mid = 0
high = n-1
While mid <= high:
If arr[mid] == 0:
swap(low, mid)
low++
mid++
Else if arr[mid] == 1:
mid++
Else:
swap(mid, high)
high--When to use
- Sorting 0/1/2
- In-place partition
Time: O(n)
public void sortColors(int[] nums) {
int low = 0, mid = 0, high = nums.length - 1;
while (mid <= high) {
if (nums[mid] == 0) {
swap(nums, low++, mid++);
} else if (nums[mid] == 1) {
mid++;
} else {
swap(nums, mid, high--);
}
}
}
private void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}6 Binary Search
low = 0
high = n-1
While low <= high:
mid = (low + high) // 2
If arr[mid] == target:
return mid
Else if arr[mid] < target:
low = mid + 1
Else:
high = mid - 1
Return -1When to use
- Sorted array
- Monotonic search space
Time: O(log n)
public int binarySearch(int[] arr, int target) {
int low = 0, high = arr.length - 1;
while (low <= high) {
int mid = low + (high - low) / 2;
if (arr[mid] == target)
return mid;
else if (arr[mid] < target)
low = mid + 1;
else
high = mid - 1;
}
return -1;
}7 Merge Intervals
Sort intervals by start
merged = []
For interval in intervals:
If merged empty OR interval.start > last.end:
add interval
Else:
last.end = max(last.end, interval.end)
Return mergedWhen to use
- Overlapping intervals
- Scheduling conflicts
Time: O(n log n)
public int[][] merge(int[][] intervals) {
Arrays.sort(intervals, (a, b) -> a[0] - b[0]);
List<int[]> merged = new ArrayList<>();
for (int[] interval : intervals) {
if (merged.isEmpty() ||
merged.get(merged.size() - 1)[1] < interval[0]) {
merged.add(interval);
} else {
merged.get(merged.size() - 1)[1] =
Math.max(merged.get(merged.size() - 1)[1], interval[1]);
}
}
return merged.toArray(new int[merged.size()][]);
}8 Hashing (Two Sum)
hashmap = empty map
For i in 0 to n-1:
complement = target - arr[i]
If complement in hashmap:
return indices
hashmap[arr[i]] = iWhen to use
- Two sum
- Frequency lookup
- Complement search
Time: O(n)
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int complement = target - nums[i];
if (map.containsKey(complement)) {
return new int[]{map.get(complement), i};
}
map.put(nums[i], i);
}
return new int[]{-1, -1};
}9 Quick Select / Heap
QuickSelect:
Pick pivot
Partition array
Recurse on correct side
Heap:
Maintain min-heap of size k
If size > k → remove root
Return heap.peek()When to use
- Kth largest/smallest
- Top K problems
public int findKthLargest(int[] nums, int k) {
PriorityQueue<Integer> pq = new PriorityQueue<>();
for (int num : nums) {
pq.offer(num);
if (pq.size() > k) {
pq.poll();
}
}
return pq.peek();
}Sliding Window Maximum (Deque)
Initialize deque
For i in 0..n-1:
Remove indices outside window
Remove smaller elements from back
Add current index
If i >= k-1:
output arr[deque.front]Time: O(n)
public int[] maxSlidingWindow(int[] nums, int k) {
Deque<Integer> deque = new LinkedList<>();
int[] result = new int[nums.length - k + 1];
int index = 0;
for (int i = 0; i < nums.length; i++) {
while (!deque.isEmpty() && deque.peekFirst() < i - k + 1)
deque.pollFirst();
while (!deque.isEmpty() && nums[deque.peekLast()] <= nums[i])
deque.pollLast();
deque.offerLast(i);
if (i >= k - 1)
result[index++] = nums[deque.peekFirst()];
}
return result;
}Premium Content
Unlock Array Revision and all premium lessons with a subscription.
All premium lessons
Ad-free experience
Priority support
From ₹199.99/year — See plans