Use two indices(left and right) moving toward each other or in the same direction.Works on sorted arrays or when searching for pairs.
Example
// JavaScript - Find pair that sums to target in sorted arrayfunctiontwoSumSorted(arr, target){let left =0, right = arr.length-1;while(left < right){const sum = arr[left]+ arr[right];if(sum === target)return[left, right];elseif(sum < target) left++;else right--;}return[-1,-1];}
# Python
def two_sum_sorted(arr, target):
left, right =0,len(arr)-1while left < right:
total = arr[left]+ arr[right]if total == target:return[left, right]
elif total < target:
left +=1else:
right -=1return[-1,-1]
Output
twoSumSorted([1,3,5,7,9], 8) → [1, 3]
Note Time O(n), Space O(1). Requires sorted input for the converging pattern. Edge cases: empty array, single element, no valid pair. Tell the interviewer you chose two pointers over hash map to achieve O(1) space.
Maintain a window[left..right] and expand/shrink to satisfy a condition.Fixed-size window: move both pointers together.Variable-size window: expand right, shrink left when constraint violated.
Example
// JavaScript - Max sum subarray of size kfunctionmaxSumWindow(arr, k){let windowSum =0, maxSum =-Infinity;for(let i =0; i < arr.length; i++){
windowSum += arr[i];if(i >= k) windowSum -= arr[i - k];if(i >= k -1) maxSum =Math.max(maxSum, windowSum);}return maxSum;}
# Python-Max sum subarray of size k
def max_sum_window(arr, k):
window_sum =0
max_sum =float('-inf')for i inrange(len(arr)):
window_sum += arr[i]if i >= k:
window_sum -= arr[i - k]if i >= k -1:
max_sum =max(max_sum, window_sum)return max_sum
Note Time O(n), Space O(1). Sliding window converts O(n*k) brute force to O(n). For variable-size windows (e.g., longest substring without repeats), use a hash set to track window contents. Always clarify: is the window fixed or variable size?
Note Build: O(n) time, O(n) space. Query: O(1). Extremely useful when you need many range sum queries. Variant: prefix XOR for range XOR problems. For 2D grids, use 2D prefix sums with inclusion-exclusion.
Track current subarray sum.If it drops below 0, reset to 0.At each step: currentSum =max(num, currentSum + num)Keep a global max.
Example
// JavaScriptfunctionmaxSubarraySum(arr){let current = arr[0], best = arr[0];for(let i =1; i < arr.length; i++){
current =Math.max(arr[i], current + arr[i]);
best =Math.max(best, current);}return best;}
# Python
def max_subarray_sum(arr):
current = best = arr[0]for num in arr[1:]:
current =max(num, current + num)
best =max(best, current)return best
Note Time O(n), Space O(1). Edge case: all negative numbers - algorithm still works since we initialize with arr[0]. To find the actual subarray indices, track start/end when best updates. Variant: maximum circular subarray uses total_sum - min_subarray.
lo =0, hi = length -1while lo <= hi:
mid = lo +(hi - lo)// 2
compare and adjust lo or hi
Example
// JavaScriptfunctionbinarySearch(arr, target){let lo =0, hi = arr.length-1;while(lo <= hi){const mid = lo +Math.floor((hi - lo)/2);if(arr[mid]=== target)return mid;if(arr[mid]< target) lo = mid +1;else hi = mid -1;}return-1;// not found}
# Python
def binary_search(arr, target):
lo, hi =0,len(arr)-1while lo <= hi:
mid = lo +(hi - lo)// 2if arr[mid]== target:return mid
elif arr[mid]< target:
lo = mid +1else:
hi = mid -1return-1
Output
binary_search([1,3,5,7,9,11], 7) → 3
Note Time O(log n), Space O(1). Off-by-one errors are the #1 bug - practice until the template is muscle memory. Use lo <= hi when searching for exact match. Use lo < hi when narrowing to a single candidate. Always test with 0, 1, and 2 element arrays.
Two pointers from ends, swap toward center.Or use built-in reverse methods.
Example
// JavaScriptfunctionreverseString(s){const chars = s.split('');let l =0, r = chars.length-1;while(l < r){[chars[l], chars[r]]=[chars[r], chars[l]];
l++; r--;}return chars.join('');}// Built-in: s.split('').reverse().join('')
# Python
def reverse_string(s):
chars =list(s)
l, r =0,len(chars)-1while l < r:
chars[l], chars[r]= chars[r], chars[l]
l +=1; r -=1return''.join(chars)
# Built-in: s[::-1]
Output
reverseString('interview') → 'weivretni'
Note Time O(n), Space O(n) due to string immutability (both JS and Python strings are immutable). In-place reversal is possible on char arrays. Common follow-ups: reverse words in a sentence, reverse only vowels, check if palindrome.
Two strings are anagrams if they have identical character frequencies.Approach1:Sort both and compare.Approach2:Build frequency map and compare.
Example
// JavaScriptfunctionisAnagram(s, t){if(s.length!== t.length)returnfalse;const freq ={};for(const ch of s) freq[ch]=(freq[ch]||0)+1;for(const ch of t){if(!freq[ch])returnfalse;
freq[ch]--;}returntrue;}
# Python
def is_anagram(s, t):iflen(s)!=len(t):returnFalse
freq ={}for ch in s:
freq[ch]= freq.get(ch,0)+1for ch in t:if freq.get(ch,0)==0:returnFalse
freq[ch]-=1returnTrue
Output
is_anagram('listen', 'silent') → True
Note Frequency map: O(n) time, O(1) space (bounded by alphabet size). Sorting approach: O(n log n). Always ask: are inputs lowercase only? Unicode? This affects space analysis. Follow-up: find all anagram groups in a list of words.
Approach1:Hashset-O(n) time,O(n) space
Approach2:Sort first -O(n log n) time,O(1) space
Approach3:Floyd's cycle(special constraints)-O(n) time,O(1) space
Example
// JavaScript - Hash set approachfunctioncontainsDuplicate(arr){const seen =newSet();for(const val of arr){if(seen.has(val))returntrue;
seen.add(val);}returnfalse;}functionfindDuplicate(arr){// Values in range [1, n], exactly one duplicateconst seen =newSet();for(const val of arr){if(seen.has(val))return val;
seen.add(val);}}
# Python
def contains_duplicate(arr):
seen =set()for val in arr:if val in seen:returnTrue
seen.add(val)returnFalse
def find_duplicate(arr):
seen =set()for val in arr:if val in seen:return val
seen.add(val)
Note The hash set approach is the go-to. If asked for O(1) space with values in [1,n], use Floyd's tortoise and hare or index marking (negate values). Always clarify constraints: can you modify the input? What is the value range?