Easy DSA Questions — Arrays and Basic Problem Solving
Start with fundamental DSA problems involving arrays, loops, conditions, counting, searching, and simple transformations. These questions build the problem-solving patterns required for more advanced algorithms.
01. Find the Largest Element in an Array
Given an array of numbers, find the largest element.
How It Works & Algorithmic Design
To find the maximum element without sorting, we use a Single-Pass Linear Scan pattern.
- Initialization: Assume the first element (
arr[0]) is the largest seen so far. Storing an element from the array ensures that negative numbers or zero values do not break the comparison logic (unlike initializing to0). - Iteration: Loop through each remaining element from left to right.
- Comparison & Update: For every element, check if it is strictly greater than our current maximum variable (
max). If it is, overwritemaxwith the new value. - Edge Case Handling: If the input array is empty (
arr.length === 0), there is no valid maximum; returnnullor an equivalent empty-state value.
Why This Approach Works Best
Alternative approaches like sorting the array first take $O(n \log n)$ time complexity. This iterative scan inspects every element exactly once, giving an optimal linear $O(n)$ runtime while using $O(1)$ constant auxiliary memory.
- Empty Input:
Returns null immediately - Comparison Count:
Exactly n - 1 comparisons for n elements
[4, 8, 2, 10, 3]Init: max=4 | Check 8 -> max=8 | Check 2 -> max=8 | Check 10 -> max=10 | Check 3 -> max=1010[-15, -3, -45, -8]-3Answer: Find maximum element
function largest(arr) {
if (!arr || arr.length === 0) return null;
let max = arr[0];
for (let i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}- Always initialize the tracking variable with an actual element from the array (like
arr[0]), not0or arbitrary values. - A single pass linear scan inspects every element once, providing $O(n)$ time complexity.
- No dynamic memory allocation is required, giving $O(1)$ constant space complexity.
02. Find the Smallest Element in an Array
Given an array of numbers, locate and return the smallest element.
How It Works & Algorithmic Design
Finding the minimum value uses the exact inverse logic of finding the maximum value:
- Initialization: Set
min = arr[0]. This establishes a benchmark value present inside the input dataset. - Linear Pass: Loop through the array from index
1toarr.length - 1. - Conditional Update: Compare each element with
min. If the current value is strictly lower (arr[i] < min), updatemin = arr[i]. - Completion: Once all $n$ elements are evaluated,
minholds the smallest value.
Why This Approach Works Best
This algorithm requires no sorting or external memory data structures. It evaluates the array in $O(n)$ time while operating in-place ($O(1)$ space).
[12, 5, 25, 1, 9]Init: min=12 | Check 5 -> min=5 | Check 25 -> min=5 | Check 1 -> min=1 | Check 9 -> min=11Answer: Find minimum element
function smallest(arr) {
if (!arr || arr.length === 0) return null;
let min = arr[0];
for (let i = 1; i < arr.length; i++) {
if (arr[i] < min) min = arr[i];
}
return min;
}- Reversing the comparison operator (
<instead of>) turns maximum-finding into minimum-finding. - Linear traversal inspects all items in $O(n)$ time.
- Always account for empty inputs before referencing index
0to prevent runtime exceptions.
03. Calculate the Sum of Array Elements
Compute the sum of all numerical values in a given array.
How It Works & Algorithmic Design
This utilizes the Accumulator Pattern:
- State Initialization: Declare an accumulator variable
total = 0. Zero acts as the additive identity element ($x + 0 = x$). - Iteration: Walk through the elements one by one.
- Accumulation: Add each element's value to
totalusing the addition assignment operator (total += element). - Return: Once the loop completes, return
total.
Why This Approach Works Best
It performs a single pass over the array with constant extra space ($O(1)$ memory). For large arrays, integer overflow should be considered depending on the language (e.g., using 64-bit integers like long in Java when working with large numbers).
[1, 2, 3, 4, 5]0 + 1 = 1 | 1 + 2 = 3 | 3 + 3 = 6 | 6 + 4 = 10 | 10 + 5 = 1515Answer: Calculate total sum
function sum(arr) {
let total = 0;
for (const value of arr) {
total += value;
}
return total;
}- Initialize accumulators with the identity element (
0for sum,1for product). - Time complexity is $O(n)$ as every element is visited once.
- In languages like Java or C++, use
longto prevent overflow when dealing with large numbers.
04. Count Even Numbers in an Array
Determine the count of even numbers contained in an array.
How It Works & Algorithmic Design
This combines Conditional Filtering with Counter Incrementation:
- Divisibility Condition: A integer $x$ is defined as even if $x \pmod 2 = 0$.
- Counter Setup: Initialize
count = 0. - Evaluation Loop: Traverse through each number in the array. Apply the modulo operator (
value % 2). If the remainder equals0, incrementcountby 1. - Negative Numbers: The condition
value % 2 === 0holds true for negative even integers as well (e.g.,-4 % 2 === 0), making this approach robust across integer domains.
Why This Approach Works Best
It processes the input in $O(n)$ runtime and $O(1)$ extra space without creating intermediate filtered arrays in memory.
[1, 4, 7, 8, 10, 13]1 (Odd) -> 4 (Even, count=1) -> 7 (Odd) -> 8 (Even, count=2) -> 10 (Even, count=3) -> 13 (Odd)3Answer: Count even values
function countEven(arr) {
let count = 0;
for (const value of arr) {
if (value % 2 === 0) count++;
}
return count;
}- Modulo operator (
%) accurately checks for divisibility. - Avoid instantiating auxiliary filtered arrays to keep space complexity at $O(1)$.
- Modulo operation works consistently for both positive and negative even integers.
05. Reverse an Array In-Place
Reverse the order of elements in an array without using extra memory allocations.
How It Works & Algorithmic Design
This demonstrates the Two Pointers Technique:
- Pointer Setup: Position a
leftpointer at index0and arightpointer at indexarr.length - 1. - Symmetric Swapping: While
left < right:- Swap the elements at
arr[left]andarr[right]. - Increment
left(left++). - Decrement
right(right--).
- Swap the elements at
- Termination: When
left >= right, the pointers meet or cross in the middle, confirming all elements have been mirrored.
Why This Approach Works Best
Creating a duplicate reversed array requires $O(n)$ auxiliary space. The two-pointer in-place swap modifies the original array directly, achieving $O(n/2) = O(n)$ time complexity and true $O(1)$ space complexity.
[10, 20, 30, 40, 50]Swap index 0 (10) & 4 (50) -> [50, 20, 30, 40, 10]Swap index 1 (20) & 3 (40) -> [50, 40, 30, 20, 10][50, 40, 30, 20, 10]Answer: Reverse in-place using two pointers
function reverse(arr) {
let left = 0, right = arr.length - 1;
while (left < right) {
let temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
left++;
right--;
}
return arr;
}- Two-pointer technique avoids extra memory overhead.
- Only $n/2$ iterations are needed to reverse an array of size $n$.
- In-place algorithm design modifies the input reference directly.
06. Check Whether an Array Is Sorted
Verify if an array's elements are ordered in non-decreasing sequence ($arr[i] \le arr[i+1]$).
How It Works & Algorithmic Design
This uses an Adjacent Pair Comparison strategy with Early Termination:
- Invariant: An array is sorted if every consecutive pair satisfied $arr[i - 1] \le arr[i]$.
- Iteration: Start looping from index
1up toarr.length - 1. - Violation Check: Compare
arr[i]against its preceding neighborarr[i - 1]. Ifarr[i] < arr[i - 1], a sorting violation has occurred. Instantly returnfalse. - Success Return: If the loop finishes without finding any out-of-order pair, return
true.
Why This Approach Works Best
It avoids checking $O(n^2)$ pairs by relying on transitivity: if $a \le b$ and $b \le c$, then $a \le c$. Comparing adjacent items in a single pass ($O(n)$ time, $O(1)$ space) is sufficient.
[2, 5, 8, 8, 12]5 >= 2 (OK) -> 8 >= 5 (OK) -> 8 >= 8 (OK) -> 12 >= 8 (OK)true[1, 3, 2, 4]3 >= 1 (OK) -> 2 < 3 (VIOLATION!)falseAnswer: Check array order
function isSorted(arr) {
for (let i = 1; i < arr.length; i++) {
if (arr[i] < arr[i - 1]) return false;
}
return true;
}- Transitivity property allows order verification through adjacent comparisons alone.
- Early return optimizes average runtime when input arrays are unsorted.
- Single-pass linear scan yields optimal $O(n)$ time performance.
07. Linear Search
Search for a specific target value within an unsorted array and return its index.
How It Works & Algorithmic Design
Linear Search inspects elements sequentially from beginning to end:
- Sequential Traversal: Loop over the array using index $i$ from $0$ to $n-1$.
- Match Evaluation: Compare
arr[i] === target. If equal, return index $i$ immediately. - Failure Case: If the iteration reaches the end of the array without a match, return
-1to signal the element was not found.
Why This Approach Works Best
When an array is unsorted, no assumptions can be made about element placement. Every position must be checked in the worst case, making linear search the optimal strategy ($O(n)$ time, $O(1)$ space) without pre-sorting.
[15, 8, 42, 4, 23]arr[0]=15 (No) -> arr[1]=8 (No) -> arr[2]=42 (MATCH!)2Answer: Linear Search implementation
function linearSearch(arr, target) {
for (let i = 0; i < arr.length; i++) {
if (arr[i] === target) return i;
}
return -1;
}- Linear search works on both sorted and unsorted collections.
- Worst-case performance is $O(n)$ when the target is absent or located at the end.
- Returns index immediately on first match, achieving best-case $O(1)$ runtime.
08. Count Occurrences of a Target
Find how many times a given target value appears within an array.
How It Works & Algorithmic Design
Unlike Linear Search (which returns early upon finding the first match), counting occurrences requires inspecting every element in the array:
- Counter Initialization: Set
count = 0. - Exhaustive Pass: Iterate through every position from index $0$ to $n-1$.
- Match Accumulation: Increment
countby $1$ every timearr[i] === target. - Final Result: Return the accumulated total after the loop finishes.
Why This Approach Works Best
Because target matches may occur multiple times across the array, early termination cannot be used. Inspecting every element gives a time complexity of $O(n)$ and $O(1)$ space.
[5, 2, 5, 8, 5, 1], Target: 55 (count=1) -> 2 -> 5 (count=2) -> 8 -> 5 (count=3) -> 13Answer: Count target frequencies
function countOccurrences(arr, target) {
let count = 0;
for (const value of arr) {
if (value === target) count++;
}
return count;
}- Requires an exhaustive scan over the entire collection.
- Runs in $O(n)$ time while keeping memory overhead at $O(1)$.
- Can be extended to count frequencies across multiple targets using a Hash Map.
09. Find the Second Largest Element
Find the second largest distinct element in an array without sorting.
How It Works & Algorithmic Design
This uses a Dual-Variable Tracking approach in a single pass:
- Variables: Maintain
first(largest) andsecond(second largest), initialized to negative infinity (-Infinity). - Iteration & Rules: Loop through each number $x$:
- Case 1 ($x > first$): A new maximum is found. Demote the old
firsttosecond(second = first), then updatefirst = x. - Case 2 ($x > second$ and $x < first$): $x$ is not the largest, but is strictly greater than
second. Updatesecond = x. - Case 3 ($x \le second$): Ignore $x$.
- Case 1 ($x > first$): A new maximum is found. Demote the old
- Distinct Constraint: The check
x < firstin Case 2 ensures duplicates of the maximum value do not improperly overwritesecond. - Result: If
secondremains-Infinity, no distinct second largest element exists; returnnull.
Why This Approach Works Best
Sorting takes $O(n \log n)$ time. Scanning twice (once for max, once for second max) takes $O(2n)$ time. This dual-variable method finds the answer in a single $O(n)$ pass using $O(1)$ memory.
[12, 35, 1, 10, 34, 1]Check 12 (first=12) -> Check 35 (second=12, first=35) -> Check 1 -> Check 10 -> Check 34 (second=34) -> Check 134Answer: Find second largest distinct element
function secondLargest(arr) {
let first = -Infinity;
let second = -Infinity;
for (const x of arr) {
if (x > first) {
second = first;
first = x;
} else if (x > second && x < first) {
second = x;
}
}
return second === -Infinity ? null : second;
}- Demote
firsttosecondwhenever a new maximum is found. - Ensure duplicates of the max value do not overwrite
secondby checkingx < first. - Solves the problem in a single pass ($O(n)$ time) without extra space ($O(1)$ memory).
10. Remove Duplicates from a Sorted Array
Given a sorted array, remove duplicate values in place such that each unique element appears only once. Return the number of unique elements.
How It Works & Algorithmic Design
This problem uses a Read/Write Two-Pointer Pattern:
- Precondition: Because the array is sorted, all duplicate elements are contiguous.
- Pointer Definitions:
write: Index where the next unique value should be placed (starts at1).read: Index used to scan through the array (starts at1).
- Scanning Logic: Compare
arr[read]with the element right before it (arr[read - 1]):- If
arr[read] !== arr[read - 1], a new unique element has been found. - Write this unique element to
arr[write], then incrementwrite(write++).
- If
- Result: The value of
writeequals the total count of unique elements, and the sub-arrayarr[0 ... write - 1]contains those unique values in order.
Why This Approach Works Best
It modifies the array in-place without creating a new set or duplicate array, running in $O(n)$ time and $O(1)$ extra space.
[0, 0, 1, 1, 1, 2, 2, 3]arr[1]=1 -> arr[2]=2 -> arr[3]=3[0, 1, 2, 3, ...]4Answer: In-place deduplication
function removeDuplicates(arr) {
if (!arr || arr.length === 0) return 0;
let write = 1;
for (let read = 1; read < arr.length; read++) {
if (arr[read] !== arr[read - 1]) {
arr[write] = arr[read];
write++;
}
}
return write;
}- Contiguous grouping in sorted arrays makes duplicate detection straightforward.
- The read pointer scans elements while the write pointer places unique values.
- Achieves $O(n)$ time complexity and $O(1)$ space complexity by modifying the array in-place.