Part 1 · Lesson 8 · 24 min read

Arrays

Many values in one variable, numbered from 0. Reading, updating, looping and the first real interview questions on arrays.

On this page

  1. An array is a row of numbered lockers
  2. Creating, reading and changing
  3. Looping over an array
  4. Adding and removing: push and pop
  5. The four patterns behind most array questions
  6. Traced: finding the maximum
  7. Copying arrays: variables share the same array
  8. Built-in methods you will use every day
  9. Sorting numbers correctly
  10. Common array mistakes
  11. Practice questions (12)
  12. Make it stick

An array is a row of numbered lockers

Imagine you must store 100 exam marks. Making 100 variables (mark1, mark2, …) would be very hard to manage.

An array is one variable that holds a list of values in order. Think of a row of lockers. Each locker holds one value. Each locker has a number, called its index. The numbering starts at 0, not 1.

marks =
72
0
85
1
90
2
64
3
↑ index (position), always starting at 0
Four values, indices 0 to 3. The last index is always length − 1.

A data structure is a way to organise data in memory so that you can use it well. Arrays are the data structure that interviews ask about most. Almost every question in Parts 4–7 uses an array or a string. So this lesson and the next one are very important.

Creating, reading and changing

JavaScript
const marks = [72, 85, 90, 64];console.log(marks[0]);                 // 72   first item: index 0console.log(marks[2]);                 // 90console.log(marks.length);             // 4    how many itemsconsole.log(marks[marks.length - 1]);  // 64   last item: index length - 1console.log(marks[10]);                // undefined  (there is no locker 10)marks[1] = 88;                         // change one itemconsole.log(marks);                    // [ 72, 88, 90, 64 ]
Three facts to never forget
  • First item: arr[0].
  • Last item: arr[arr.length - 1].
  • Valid indices: 0 to arr.length - 1. An index outside this range gives undefined (“no value”).

Looping over an array

In Lesson 4 you saw that “start at 0 and use <” is the most common loop in DSA. Here is why. The variable i takes exactly the values 0 to length − 1. That is every valid index, once.

JavaScript
const nums = [4, 8, 15];// 1. Index loop: use it when you need the position ifor (let i = 0; i < nums.length; i++) {  console.log(i, nums[i]);}// 2. for...of: use it when you only need the valuesfor (const x of nums) {  console.log(x);}/* Output:0 41 82 154815*/

Use the index loop when the position matters. For example, you need it to compare neighbours, to swap items or to return an index. Use for…of when you only need each value. (for…of is a loop that gives you each value of an array, one at a time.)

Adding and removing: push and pop

JavaScript
const stack = [1, 2];stack.push(3);        // add to the END       → [1, 2, 3]stack.push(4);        //                      → [1, 2, 3, 4]const last = stack.pop();  // remove from the END, returns itconsole.log(last);    // 4console.log(stack);   // [ 1, 2, 3 ]const empty = [];     // start empty and fill it in a loop (very common)for (let i = 1; i <= 3; i++) empty.push(i * i);console.log(empty);   // [ 1, 4, 9 ]

push is a method that adds an item to the end of an array. pop is a method that removes the last item and gives it back to you. (A method is a function that belongs to an object, here the array. You call it with a dot, like stack.push(3).) Both are fast, because no other item has to move.

There are also unshift and shift. They add and remove at the front. They can be slow on large arrays, because every other item may have to move one place. Lesson 12 explains why that matters.

The four patterns behind most array questions

PatternBefore the loopInside the loopExamples
Accumulatelet sum = 0sum += arr[i]sum, average, product
Best so farlet max = arr[0]replace if bettermax, min, longest word
Countlet count = 0if (…) count++count evens, count negatives
Search—if (arr[i] === target) return ifind an index, “does it contain…?”

These are the loop patterns from Lessons 4–5, now used on arrays. Searching item by item from the start is called a linear search. Part 6 will show a much faster way when the array is sorted.

Traced: finding the maximum

step 1 / 14
Set up
The input array

Five numbers at indices 0 to 4.

▶const nums = [3, 7, 2, 9, 4];2let max = nums[0];3for (let i = 1; i < nums.length; i++) {4  if (nums[i] > max) {5    max = nums[i];6  }7}8console.log(max);
Variables
nums[3, 7, 2, 9, 4]
Console
(nothing printed yet)
“Best so far” in action: max only changes when a bigger value appears (at 7 and at 9). · interactive

Copying arrays: variables share the same array

A variable does not hold the array itself. It holds a reference. A reference is the address of the place in memory where the array lives. When you write const b = a, you copy the address, not the lockers. Both variables then point to the same array:

JavaScript
const a = [1, 2, 3];const b = a;          // NOT a copy — b points at the SAME arrayb.push(4);console.log(a);       // [ 1, 2, 3, 4 ]  ← a changed too!const c = [...a];     // a real copy (spread syntax)c.push(5);console.log(a);       // [ 1, 2, 3, 4 ]  unchangedconsole.log(c);       // [ 1, 2, 3, 4, 5 ]

This matters when you pass an array into a function. The function can change your array. When a question says “do it in place”, it wants exactly that: change the original array. When a question says “return a new array”, copy the array first. The [...a] form is called spread syntax. It takes every item out of a and puts them in a new array.

Built-in methods you will use every day

JavaScript arrays come with ready-made methods that do common jobs. Each one runs a loop inside, so it still takes time on a large array. But the methods make your code much shorter.

Searching and copying

JavaScript
const nums = [5, 3, 8, 3];console.log(nums.includes(8));    // true   is 8 anywhere in the array?console.log(nums.indexOf(3));     // 1      first position of 3, or -1console.log(nums.lastIndexOf(3)); // 3      last position of 3console.log(nums.slice(1, 3));    // [ 3, 8 ]  a COPY of positions 1 and 2 (position 3 is not included)console.log(nums.slice());        // [ 5, 3, 8, 3 ]  a full copy

Removing and inserting in the middle: splice

JavaScript
const nums = [10, 20, 30, 40];nums.splice(1, 1);             // at position 1, remove 1 itemconsole.log(nums);             // [ 10, 30, 40 ]nums.splice(1, 0, 15, 25);     // at position 1, remove 0 items, insert 15 and 25console.log(nums);             // [ 10, 15, 25, 30, 40 ]

splice changes the array itself. Every item after the change has to move, so it takes longer on large arrays. slice (without the “p”) never changes the original. It returns a copy of a part of the array. Do not mix them up.

map, filter and reduce

These three methods each take a small function and run it on every item. A function you pass to another function is called a callback. Here the callbacks are arrow functions (Lesson 7).

  • map makes a new array of the same length. Each new item is the callback's result for the old item.
  • filter makes a new array with only the items for which the callback returns true.
  • reduce combines all items into one value. The callback receives the total so far and the next item. The last argument (here 0) is the starting total.

Here they are in code:

JavaScript
const prices = [100, 250, 40, 80];// map: make a NEW array by changing every item (here: add 10 percent)const withTax = prices.map((p) => p * 1.1);console.log(withTax.map(Math.round));          // [ 110, 275, 44, 88 ]// filter: make a NEW array with only the items that pass a testconst cheap = prices.filter((p) => p < 100);console.log(cheap);                            // [ 40, 80 ]// reduce: combine all items into ONE valueconst total = prices.reduce((sum, p) => sum + p, 0);console.log(total);                            // 470
MethodReturnsChanges the original?
includes, indexOftrue/false, a positionNo
slice, map, filtera new arrayNo
reduceone valueNo
push, pop, splice, sort, reverse(varies)Yes

Sorting numbers correctly

sort() is a method that puts the items of an array in order. With no arguments, it compares items as text. So "100" comes before "25", because “1” comes before “2”. For numbers, always pass a comparison function. This is a function that takes two items, a and b. If it returns a negative number, a goes first. If it returns a positive number, b goes first.

JavaScript
const nums = [10, 9, 1, 100, 25];console.log([...nums].sort());                  // [ 1, 10, 100, 25, 9 ]  ✗ sorted as TEXTconsole.log([...nums].sort((a, b) => a - b));   // [ 1, 9, 10, 25, 100 ]  ✓ smallest firstconsole.log([...nums].sort((a, b) => b - a));   // [ 100, 25, 10, 9, 1 ]  ✓ largest first
Remember

(a, b) => a - b sorts from smallest to largest. sort changes the original array, so the examples sort a copy ([...nums]). Part 3 explains how sorting works inside.

Common array mistakes

MistakeFix
i <= arr.length — reads arr[length], which is undefinedUse i < arr.length
let max = 0 on an array of negatives returns 0Start with arr[0]
sort() on numbers without a comparison functionsort((a, b) => a - b)
Forgetting the empty array []Ask what to return for it; check arr.length === 0 first
b = a and expecting a copyb = [...a]

Practice questions

Q1Sum of an arrayEasy

Return the sum of all numbers in the array.

Example 1
Input: [3, 7, 2, 9]
Output: 21
Explanation: 3 + 7 + 2 + 9 = 21.
Example 2
Input: []
Output: 0
Explanation: An empty array has nothing to add, so the sum is 0.
Stuck? Open one hint at a time
Hint 1
This is the accumulate pattern: make a variable before the loop and update it inside the loop.
Show all 3 solutions with explanations
Approach 1Index loop
The idea

Start sum at 0 and add arr[i] for every index.

JavaScript
function sumArray(arr) {  let sum = 0;  for (let i = 0; i < arr.length; i++) {    sum += arr[i];  }  return sum;}console.log(sumArray([3, 7, 2, 9])); // 21console.log(sumArray([]));           // 0
How it works

For an empty array, the loop never runs and 0 is returned. That is correct, with no special case.

Approach 2for…of
The idea

You do not need the position, so loop over the values directly.

JavaScript
function sumArray(arr) {  let sum = 0;  for (const x of arr) sum += x;  return sum;}console.log(sumArray([3, 7, 2, 9])); // 21
How it works

This is shorter. It also avoids an off-by-one error (a mistake where the loop runs one time too many or too few).

Approach 3reduce
The idea

reduce is an array method that combines all items into one value. Here it starts from 0 and adds each item.

JavaScript
const sumArray = (arr) => arr.reduce((sum, x) => sum + x, 0);console.log(sumArray([3, 7, 2, 9])); // 21console.log(sumArray([]));           // 0
How it works

The 0 at the end is the starting value. If you leave it out, reduce throws an error on an empty array.

Which approach should you use?

All three are correct. In interviews, the loop versions are the clearest. reduce is common in everyday JavaScript.

Q2Largest elementEasy

Return the largest number in a non-empty array.

Example 1
Input: [3, 7, 2, 9, 4]
Output: 9
Explanation: 9 is larger than every other value.
Example 2
Input: [-5, -2, -9]
Output: -2
Explanation: All values are negative, and -2 is the largest. If max started at 0, the function would wrongly return 0.
Stuck? Open one hint at a time
Hint 1
Keep a “best so far” variable. What should it start as?
Hint 2
Start with arr[0], not 0. Then arrays of negative numbers also work.
Show all 3 solutions with explanations
Approach 1Best so far
The idea

Start with the first item. Replace it whenever a larger item appears.

JavaScript
function largest(arr) {  let max = arr[0];  for (let i = 1; i < arr.length; i++) {    if (arr[i] > max) max = arr[i];  }  return max;}console.log(largest([3, 7, 2, 9, 4])); // 9console.log(largest([-5, -2, -9]));    // -2
How it works

It goes through the array one time (one pass). This is the traced example in the lesson.

Approach 2Math.max with spread
The idea

Math.max takes separate numbers, not an array. The spread syntax ...arr turns the array into separate arguments.

JavaScript
const largest = (arr) => Math.max(...arr);console.log(largest([3, 7, 2, 9, 4])); // 9
How it works

This is short and correct for normal sizes. For extremely large arrays (about a hundred thousand items or more), spreading can fail with an error, so the loop is safer.

Approach 3Sort a copy and take the last item
The idea

After sorting from smallest to largest, the largest value is at the end.

JavaScript
function largest(arr) {  const sorted = [...arr].sort((a, b) => a - b);  return sorted[sorted.length - 1];}console.log(largest([3, 7, 2, 9, 4])); // 9
How it works

This is correct, but sorting does far more work than one pass (Lesson 12). Mention it only to show that you know why it is not the best choice.

Which approach should you use?

Use Approach 1. It does the least work and it works for every size of array.

Q3Count the even numbersEasy

How many numbers in the array are even?

Example 1
Input: [1, 4, 6, 7, 10]
Output: 3
Explanation: 4, 6 and 10 are even.
Stuck? Open one hint at a time
Hint 1
A counter is a variable that counts things. Start it at 0 and add 1 for each even value.
Show all 2 solutions with explanations
Approach 1Loop and count
The idea

This is the count pattern. The counter goes up only when the condition is true.

JavaScript
function countEvens(arr) {  let count = 0;  for (const x of arr) {    if (x % 2 === 0) count++;  }  return count;}console.log(countEvens([1, 4, 6, 7, 10])); // 3
How it works

The position does not matter here, so for…of is enough.

Approach 2filter, then length
The idea

filter keeps only the items that pass a test. Keep the even values, then count how many were kept.

JavaScript
const countEvens = (arr) => arr.filter((x) => x % 2 === 0).length;console.log(countEvens([1, 4, 6, 7, 10])); // 3
How it works

This is easy to read, but it builds a temporary array only to count it.

Which approach should you use?

Approach 1 uses no extra memory. Approach 2 is fine for small inputs, and it reads like the problem.

Q4Linear searchEasy

Return the index of the first occurrence of target, or −1 if it is not there.

Example 1
Input: arr = [5, 3, 8, 3], target = 3
Output: 1
Explanation: 3 appears at positions 1 and 3. The first one is at 1.
Example 2
Input: arr = [5, 3, 8], target = 4
Output: -1
Explanation: 4 is not in the array.
Stuck? Open one hint at a time
Hint 1
The target is the value you are looking for. Check each position from the start. When you find the target, return its position at once.
Hint 2
If the loop ends and you did not find it, return -1.
Show all 3 solutions with explanations
Approach 1Index loop with early return
The idea

Return the first matching index. If nothing matches, return -1 after the loop.

JavaScript
function indexOf(arr, target) {  for (let i = 0; i < arr.length; i++) {    if (arr[i] === target) return i;  }  return -1;}console.log(indexOf([5, 3, 8, 3], 3)); // 1console.log(indexOf([5, 3, 8], 4));    // -1
How it works

This is the search pattern. It needs the index, so it uses an index loop and not for…of.

Approach 2Built-in indexOf
The idea

Arrays already have a method for this.

JavaScript
console.log([5, 3, 8, 3].indexOf(3)); // 1console.log([5, 3, 8].indexOf(4));    // -1
How it works

It does exactly what Approach 1 does: it checks items one by one. This tells you how long it takes on a big array: longer for more items.

Approach 3findIndex with a condition
The idea

findIndex returns the index of the first item that passes a test you give it. It returns -1 if no item passes.

JavaScript
const nums = [5, 3, 8, 3];console.log(nums.findIndex((x) => x > 6)); // 2   first item greater than 6
How it works

Use it when you search for a condition and not for an exact value.

Which approach should you use?

Be able to write Approach 1. Use the built-in methods in real code. If the array is sorted, binary search (Lesson 28) is much faster.

Q5Reverse an arrayEasy

Reverse the array. Try to do it without creating a second array.

Example 1
Input: [1, 2, 3, 4, 5]
Output: [5, 4, 3, 2, 1]
Explanation: The first item becomes the last, the second item becomes the second from last, and so on.
Example 2
Input: [7]
Output: [7]
Explanation: A single item stays where it is.
Stuck? Open one hint at a time
Hint 1
Swap the first and last items. Then swap the second and the second from last, and so on.
Hint 2
Use two indexes, left and right, that move towards each other. Stop when they meet.
Show all 3 solutions with explanations
Approach 1Two pointers, in place
The idea

A pointer is a variable that holds an index. Swap the two ends, move both pointers inwards, and repeat until they meet.

JavaScript
function reverseInPlace(arr) {  let left = 0;  let right = arr.length - 1;  while (left < right) {    const temp = arr[left];    arr[left] = arr[right];    arr[right] = temp;    left++;    right--;  }  return arr;}console.log(reverseInPlace([1, 2, 3, 4, 5])); // [ 5, 4, 3, 2, 1 ]console.log(reverseInPlace([7]));             // [ 7 ]
How it works
Dry run · [1, 2, 3, 4, 5]
leftrightswaparray after
041 ↔ 5[5, 2, 3, 4, 1]
132 ↔ 4[5, 4, 3, 2, 1]
22left < right is false — stop
Approach 2Build a new array backwards
The idea

Walk from the last index to the first and push each item into a new array.

JavaScript
function reversed(arr) {  const result = [];  for (let i = arr.length - 1; i >= 0; i--) {    result.push(arr[i]);  }  return result;}console.log(reversed([1, 2, 3])); // [ 3, 2, 1 ]
How it works

This is simple, and the original array is unchanged. But it uses a second array of the same size.

Approach 3Built-in reverse
The idea

arr.reverse() reverses the array in place (it changes the original).

JavaScript
const nums = [1, 2, 3];nums.reverse();console.log(nums); // [ 3, 2, 1 ]
How it works

It changes the original array. Use [...nums].reverse() if you want to keep the original.

Which approach should you use?

If the question says “in place” or “without extra memory”, use Approach 1. It is your first two-pointer solution. Lesson 21 builds a whole pattern on it.

Q6Is the array sorted?Easy

Return true if the array is in non-decreasing order (each item is at least as big as the one before it).

Example 1
Input: [1, 2, 2, 5]
Output: true
Explanation: Every item is greater than or equal to the item before it.
Example 2
Input: [1, 3, 2]
Output: false
Explanation: 2 is smaller than the 3 before it.
Stuck? Open one hint at a time
Hint 1
Compare each item with the item just before it.
Hint 2
Start the loop at index 1, because index 0 has no item before it.
Show all 3 solutions with explanations
Approach 1Compare neighbours
The idea

If any item is smaller than the item before it, the array is not sorted.

JavaScript
function isSorted(arr) {  for (let i = 1; i < arr.length; i++) {    if (arr[i] < arr[i - 1]) return false;  }  return true;}console.log(isSorted([1, 2, 2, 5])); // trueconsole.log(isSorted([1, 3, 2]));    // false
How it works

One drop anywhere is enough to answer false, so the function can stop early.

Approach 2every()
The idea

every is an array method that checks whether a test is true for every item. It returns true or false.

JavaScript
const isSorted = (arr) => arr.every((x, i) => i === 0 || arr[i - 1] <= x);console.log(isSorted([1, 2, 2, 5])); // trueconsole.log(isSorted([1, 3, 2]));    // false
How it works

The callback's second argument i is the position of the item. Like Approach 1, every stops at the first failure.

Approach 3Compare with a sorted copy
The idea

Sort a copy and check whether it matches the original.

JavaScript
function isSorted(arr) {  const sorted = [...arr].sort((a, b) => a - b);  return sorted.every((x, i) => x === arr[i]);}console.log(isSorted([1, 3, 2])); // false
How it works

This is correct, but sorting is much more work than one pass. Avoid it here.

Which approach should you use?

Use Approach 1.

Q7Second largest (distinct)Medium

Return the second largest distinct value, or −1 if there isn't one.

Example 1
Input: [12, 35, 1, 10, 34, 1]
Output: 34
Explanation: The largest is 35. The largest value below it is 34.
Example 2
Input: [10, 10, 10]
Output: -1
Explanation: Only one distinct value exists, so there is no second largest.
Stuck? Open one hint at a time
Hint 1
Simple idea: find the largest value first. Then find the largest value that is smaller than it.
Hint 2
One-pass idea: keep two variables, first and second. When a new largest value arrives, the old largest becomes second.
Show all 3 solutions with explanations
Approach 1Two passes
The idea
  1. Pass 1: find the largest value.
  2. Pass 2: find the largest value that is strictly smaller.
JavaScript
function secondLargest(arr) {  let first = -Infinity;  for (const x of arr) if (x > first) first = x;  let second = -Infinity;  for (const x of arr) if (x < first && x > second) second = x;  return second === -Infinity ? -1 : second;}console.log(secondLargest([12, 35, 1, 10, 34, 1])); // 34console.log(secondLargest([10, 10, 10]));           // -1
How it works

-Infinity is a special JavaScript value that is smaller than every other number, so it is a safe starting value. This approach is easy to get right.

Approach 2One pass with two variables
The idea

Track the largest and the second largest in the same loop.

JavaScript
function secondLargest(arr) {  let first = -Infinity, second = -Infinity;  for (const x of arr) {    if (x > first) {      second = first;    // the old largest moves down      first = x;    } else if (x > second && x < first) {      second = x;    }  }  return second === -Infinity ? -1 : second;}console.log(secondLargest([12, 35, 1, 10, 34, 1])); // 34console.log(secondLargest([10, 10, 10]));           // -1
How it works
Dry run · [12, 35, 1, 10, 34, 1]
xrulefirstsecond
12new largest12-∞
35new largest3512
1nothing3512
10nothing3512
34between3534
1nothing3534
Approach 3Remove duplicates and sort
The idea

A Set is a collection that keeps each value only once (Lesson 10). Put the array in a Set to keep only distinct values. Then sort them and take the second from the end.

JavaScript
function secondLargest(arr) {  const unique = [...new Set(arr)].sort((a, b) => a - b);  return unique.length < 2 ? -1 : unique[unique.length - 2];}console.log(secondLargest([12, 35, 1, 10, 34, 1])); // 34console.log(secondLargest([10, 10, 10]));           // -1
How it works

This is short, but sorting does more work than needed. It is good to mention, but it is not the best answer.

Which approach should you use?

Approach 2 is the answer interviewers look for (one pass, no extra memory). Approach 1 is a good first answer that you can then improve.

Q8Remove duplicates from a sorted arrayMedium

Given a sorted array, keep each value only once.

Example 1
Input: [1, 1, 2, 3, 3, 3, 4]
Output: [1, 2, 3, 4]
Explanation: Each value is kept once, in order.
Example 2
Input: []
Output: []
Explanation: Nothing to remove.
Stuck? Open one hint at a time
Hint 1
In a sorted array, equal values are always next to each other.
Hint 2
Keep an item only if it is different from the item before it.
Show all 3 solutions with explanations
Approach 1Build a new array
The idea

Push an item into the new array if it is the first item or if it is different from the previous one.

JavaScript
function uniqueSorted(arr) {  const result = [];  for (let i = 0; i < arr.length; i++) {    if (i === 0 || arr[i] !== arr[i - 1]) result.push(arr[i]);  }  return result;}console.log(uniqueSorted([1, 1, 2, 3, 3, 3, 4])); // [ 1, 2, 3, 4 ]console.log(uniqueSorted([]));                    // []
How it works

The input is sorted, so checking the neighbour is enough.

Approach 2In place with a write pointer
The idea

Keep a position k where the next unique value will be written (a “write pointer”). Copy each new value to arr[k]. At the end, the first k items are the answer.

JavaScript
function removeDuplicates(arr) {  if (arr.length === 0) return 0;  let k = 1;                                // arr[0] is always kept  for (let i = 1; i < arr.length; i++) {    if (arr[i] !== arr[k - 1]) {      arr[k] = arr[i];      k++;    }  }  return k;                                 // number of unique values}const nums = [1, 1, 2, 3, 3, 3, 4];const k = removeDuplicates(nums);console.log(k, nums.slice(0, k)); // 4 [ 1, 2, 3, 4 ]
How it works

This is exactly LeetCode 26: return the count and leave the unique values at the front of the array. No second array is used.

Approach 3Set
The idea

A Set is a collection that keeps each value only once (Lesson 10). Spread it back into an array.

JavaScript
const uniqueSorted = (arr) => [...new Set(arr)];console.log(uniqueSorted([1, 1, 2, 3, 3, 3, 4])); // [ 1, 2, 3, 4 ]
How it works

This works even if the array is not sorted. But it uses extra memory and it is not “in place”.

Which approach should you use?

For LeetCode 26 you must use Approach 2. Approach 1 is the easiest to write. Approach 3 is the everyday shortcut.

Q9Rotate left by oneEasy

Move every element one position to the left; the first element goes to the end.

Example 1
Input: [1, 2, 3, 4, 5]
Output: [2, 3, 4, 5, 1]
Explanation: Every item moves one place to the left. The first item goes round to the end.
Stuck? Open one hint at a time
Hint 1
Save the first item before it is overwritten.
Hint 2
Shift every other item one place left, then put the saved item at the end.
Show all 3 solutions with explanations
Approach 1Save, shift, place
The idea

Save arr[0], move each item one place left, put the saved item last.

JavaScript
function rotateLeftOne(arr) {  if (arr.length === 0) return arr;  const first = arr[0];  for (let i = 1; i < arr.length; i++) {    arr[i - 1] = arr[i];  }  arr[arr.length - 1] = first;  return arr;}console.log(rotateLeftOne([1, 2, 3, 4, 5])); // [ 2, 3, 4, 5, 1 ]
How it works

This is the same idea as the swap in Lesson 2: save a value before you overwrite it.

Approach 2shift and push
The idea

shift() removes the first item and returns it. push adds it to the end.

JavaScript
const nums = [1, 2, 3, 4, 5];nums.push(nums.shift());console.log(nums); // [ 2, 3, 4, 5, 1 ]
How it works

This is one line. But shift() may have to move every other item, so it can do about the same amount of work as Approach 1.

Approach 3slice and join two pieces
The idea

slice(1) copies everything after the first item. The answer is that copy, followed by the first item.

JavaScript
const rotateLeftOne = (arr) => [...arr.slice(1), arr[0]];console.log(rotateLeftOne([1, 2, 3, 4, 5])); // [ 2, 3, 4, 5, 1 ]
How it works

This builds a new array and leaves the original unchanged. Lesson 19 extends the idea to rotating by k positions.

Which approach should you use?

Approach 1 shows that you understand what happens to each item. Approaches 2 and 3 are fine in everyday code.

Q10Move zeros to the endMedium

Move all zeros to the end, keeping the other numbers in their original order. Do it in place. (LeetCode 283.)

Example 1
Input: [0, 1, 0, 3, 12]
Output: [1, 3, 12, 0, 0]
Explanation: The non-zero values keep their order (1, 3, 12) and the two zeros go to the end.
Example 2
Input: [0]
Output: [0]
Explanation: Nothing to move.
Stuck? Open one hint at a time
Hint 1
Keep a position k. It means “where the next non-zero value should go”.
Hint 2
Copy every non-zero value to position k and move k forward. After the loop, fill everything from k to the end with zeros.
Show all 3 solutions with explanations
Approach 1Write pointer, then fill zeros
The idea

Move the non-zero values to the front. Then fill the rest with zeros.

JavaScript
function moveZeros(arr) {  let k = 0;  for (let i = 0; i < arr.length; i++) {    if (arr[i] !== 0) {      arr[k] = arr[i];      k++;    }  }  while (k < arr.length) {    arr[k] = 0;    k++;  }  return arr;}console.log(moveZeros([0, 1, 0, 3, 12])); // [ 1, 3, 12, 0, 0 ]
How it works
Dry run · [0, 1, 0, 3, 12]
iarr[i]actionk after
00skip0
11arr[0] = 11
20skip1
33arr[1] = 32
412arr[2] = 123
—fill arr[3], arr[4] with 05
Approach 2Swap non-zeros forward
The idea

When arr[i] is not zero, swap it with arr[k]. The zeros move back on their own.

JavaScript
function moveZeros(arr) {  let k = 0;  for (let i = 0; i < arr.length; i++) {    if (arr[i] !== 0) {      [arr[k], arr[i]] = [arr[i], arr[k]];   // swap two items in one line      k++;    }  }  return arr;}console.log(moveZeros([0, 1, 0, 3, 12])); // [ 1, 3, 12, 0, 0 ]
How it works

This uses one loop and no second pass. Each swap moves a non-zero value forward and a zero backward.

Approach 3filter, then add zeros
The idea

Make a new array of the non-zero values. Then add the right number of zeros.

JavaScript
function moveZeros(arr) {  const nonZero = arr.filter((x) => x !== 0);  const zeros = new Array(arr.length - nonZero.length).fill(0);  return [...nonZero, ...zeros];}console.log(moveZeros([0, 1, 0, 3, 12])); // [ 1, 3, 12, 0, 0 ]
How it works

This is easy to read. But it creates new arrays, so it does not meet the “in place” rule of LeetCode 283.

Which approach should you use?

For LeetCode 283, use Approach 1 or 2 (both are in place). Approach 2 is slightly shorter. Approach 1 is easier to trace.

Q11Running sumEasy

Return an array where position i holds the sum of nums[0] to nums[i]. (LeetCode 1480.)

Example 1
Input: [1, 2, 3, 4]
Output: [1, 3, 6, 10]
Explanation: Each position holds the total so far: 1, 1+2, 1+2+3, 1+2+3+4.
Example 2
Input: [3, 1, 2, 10, 1]
Output: [3, 4, 6, 16, 17]
Explanation: 3, 3+1, 4+2, 6+10, 16+1.
Stuck? Open one hint at a time
Hint 1
Keep a running total. After you add each item, save the total.
Show all 2 solutions with explanations
Approach 1New array with a running total
The idea

Add each item to total and push the total into a new array.

JavaScript
function runningSum(nums) {  const result = [];  let total = 0;  for (const x of nums) {    total += x;    result.push(total);  }  return result;}console.log(runningSum([1, 2, 3, 4])); // [ 1, 3, 6, 10 ]
How it works

This is the accumulator pattern. It saves the total after every step.

Approach 2In place
The idea

Each position becomes its own value plus the position before it (which is already updated).

JavaScript
function runningSum(nums) {  for (let i = 1; i < nums.length; i++) {    nums[i] += nums[i - 1];  }  return nums;}console.log(runningSum([3, 1, 2, 10, 1])); // [ 3, 4, 6, 16, 17 ]
How it works

This uses no extra array. A running total like this is called a prefix sum. Lesson 20 shows how it answers “sum of any range” questions very fast.

Which approach should you use?

Both are correct for LeetCode 1480. Use Approach 2 if you may change the input. Otherwise, use Approach 1.

Q12Max consecutive onesEasy

Given an array of 0s and 1s, return the length of the longest run of consecutive 1s. (LeetCode 485.)

Example 1
Input: [1, 1, 0, 1, 1, 1]
Output: 3
Explanation: The longest run of 1s is the last three.
Example 2
Input: [1, 0, 1, 1, 0, 1]
Output: 2
Explanation: The longest run is the two 1s in the middle.
Stuck? Open one hint at a time
Hint 1
A run is a group of 1s next to each other. Keep a counter for the current run. What should happen to it when you see a 0?
Hint 2
Also keep the best run so far. Update it as the current run grows.
Show all 2 solutions with explanations
Approach 1Current run and best run
The idea

Add 1 to current when you see a 1. Reset it to 0 when you see a 0. Keep the largest value it reaches.

JavaScript
function findMaxConsecutiveOnes(nums) {  let current = 0, best = 0;  for (const x of nums) {    if (x === 1) {      current++;      best = Math.max(best, current);    } else {      current = 0;    }  }  return best;}console.log(findMaxConsecutiveOnes([1, 1, 0, 1, 1, 1])); // 3console.log(findMaxConsecutiveOnes([1, 0, 1, 1, 0, 1])); // 2
How it works

This joins two patterns: a counter that resets, and “best so far”. It needs one pass.

Approach 2Split the text at the zeros
The idea

Join the array into text like "110111". Split the text at every 0. Then find the longest piece.

JavaScript
function findMaxConsecutiveOnes(nums) {  const pieces = nums.join("").split("0");   // "110111" → ["11", "111"]  return Math.max(...pieces.map((p) => p.length));}console.log(findMaxConsecutiveOnes([1, 1, 0, 1, 1, 1])); // 3
How it works

This is a creative shortcut. It builds text and several arrays, so it uses much more memory than Approach 1.

Which approach should you use?

Use Approach 1 for LeetCode 485. Approach 2 shows that a different way of thinking can give an unusual solution.

Make it stick

Make it stick — close this page, then
  1. Write the four array patterns (accumulate, best so far, count, search) from memory, one line each.
  2. Reverse [a, b, c, d] in place on paper with left/right pointers.
  3. Explain why const b = a doesn't copy an array, and how to copy one.

Revisit schedule: solve two of the questions again tomorrow, again in 3 days, and once more in a week — without looking at the answers. Each time it will feel easier. That is the memory forming.

Next lesson: strings. A string is text. It works like an array of characters, but you can read it and not change it.

Practise on LeetCode

Real interview problems that use exactly what this lesson teaches. Solve them in JavaScript after the practice questions above.

Published by Jainik · Last updated · How these lessons are made

Keep learning

Related series