Remove Element
Problem Statement
Section titled “Problem Statement”Given an integer array nums and an integer val, remove all occurrences of val in-place. The order of the elements may be changed. Then return the number of elements in nums which are not equal to val.
Consider the number of elements in nums which are not equal to val be k, then you need to do the following things to be accepted:
- Change the first
kelements ofnumssuch that they contain all the elements which are not equal toval. - The remaining elements of
numsare not important as well as the size ofnums. - Return
k.
Examples
Section titled “Examples”| Input | val | Output | Array After | Explanation |
|---|---|---|---|---|
[3,2,2,3] | 3 | 2 | [2,2,_,_] | The first 2 elements are [2, 2]; rest don’t matter |
[0,1,2,2,3,0,4,2] | 2 | 5 | [0,1,4,0,3,_,_,_] | The first 5 elements contain no 2 |
[2] | 3 | 1 | [2] | No element equals 3 |
Constraints
Section titled “Constraints”0 <= nums.length <= 1000 <= nums[i] <= 500 <= val <= 100
Real-World Applications
Section titled “Real-World Applications”Complexity Comparison
Section titled “Complexity Comparison”| Approach | Time | Space | Best When |
|---|---|---|---|
| Two Pointers | O(n) | O(1) | General case — single pass, optimal space |
| Brute Force | O(n²) | O(1) | Array is tiny, demonstrating the concept |
Which approach should you learn first?
Section titled “Which approach should you learn first?”- Pick Two Pointers to understand the efficient partition technique — it’s the expected solution in interviews.
- Pick Brute Force if you’re still learning how to modify arrays in-place.
Approach 1: Two Pointers (Recommended)
Section titled “Approach 1: Two Pointers (Recommended)”Use two pointers: read scans the array, and write tracks where to place non-val elements. When read finds a value that is not val, copy it to the write position and increment both pointers. The first write elements will contain all non-val values.
The key insight is that we partition the array into two regions: the first write elements are valid, and the rest are ignored.
Step-by-step Example
Section titled “Step-by-step Example”Input: nums = [0,1,2,2,3,0,4,2], val = 2
| Step | read | write | nums[read] | Action | Array State |
|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 ≠ 2 → copy to write | [0,1,2,2,3,0,4,2], write++ |
| 1 | 1 | 1 | 1 | 1 ≠ 2 → copy to write | [0,1,2,2,3,0,4,2], write++ |
| 2 | 2 | 2 | 2 | 2 == 2 → skip | [0,1,2,2,3,0,4,2], read++ only |
| 3 | 3 | 2 | 2 | 2 == 2 → skip | [0,1,2,2,3,0,4,2], read++ only |
| 4 | 4 | 2 | 3 | 3 ≠ 2 → copy to write | [0,1,3,2,3,0,4,2], write++ |
| 5 | 5 | 3 | 0 | 0 ≠ 2 → copy to write | [0,1,3,0,3,0,4,2], write++ |
| 6 | 6 | 4 | 4 | 4 ≠ 2 → copy to write | [0,1,3,0,4,0,4,2], write++ |
| 7 | 7 | 5 | 2 | 2 == 2 → skip | Done, return 5 |
Final result: First 5 elements [0, 1, 3, 0, 4] contain no 2.
Animated walkthrough
Use Next or Autoplay to watch the read pointer scan for non-val elements while the write pointer builds the valid partition.
Pseudocode
Section titled “Pseudocode”function removeElement(nums, val): write = 0 for read in range(len(nums)): if nums[read] != val: nums[write] = nums[read] write++ return writeSolution Code
Section titled “Solution Code”"""Remove all occurrences of a value in-place from an array and return the new length.
Approach: Two PointersUse a 'write' pointer to place non-val elements and a 'read' pointer to scan the array.When read finds a non-val element, copy it to the write position and advance both.When read finds a val element, skip it and only advance read.
Time Complexity: O(n) — single pass through the arraySpace Complexity: O(1) — no extra data structures
Example 1:Input: nums = [3,2,2,3], val = 3Output: 2Array after: [2,2,_,_]Explanation: The first 2 elements are [2, 2]; elements after position 2 are ignored.
Example 2:Input: nums = [0,1,2,2,3,0,4,2], val = 2Output: 5Array after: [0,1,4,0,3,_,_,_]Explanation: The first 5 elements contain no 2."""
from typing import List
def remove_element(nums: List[int], val: int) -> int: write = 0 for read in range(len(nums)): if nums[read] != val: nums[write] = nums[read] write += 1 return write
# Test casesprint(remove_element([3, 2, 2, 3], val=3)) # 2print(remove_element([0, 1, 2, 2, 3, 0, 4, 2], val=2)) # 5print(remove_element([2], val=3)) # 1print(remove_element([], val=0)) # 0#include <vector>using namespace std;
/*Remove all occurrences of a value in-place from an array and return the new length.
Approach: Two PointersUse a 'write' pointer to place non-val elements and a 'read' pointer to scan the array.When read finds a non-val element, copy it to the write position and advance both.When read finds a val element, skip it and only advance read.
Time Complexity: O(n) — single pass through the arraySpace Complexity: O(1) — no extra data structures
Example 1:Input: nums = [3,2,2,3], val = 3Output: 2Array after: [2,2,_,_]Explanation: The first 2 elements are [2, 2]; elements after position 2 are ignored.
Example 2:Input: nums = [0,1,2,2,3,0,4,2], val = 2Output: 5Array after: [0,1,4,0,3,_,_,_]Explanation: The first 5 elements contain no 2.*/
class Solution {public: int removeElement(vector<int>& nums, int val) { int write = 0; for (int read = 0; read < nums.size(); read++) { if (nums[read] != val) { nums[write] = nums[read]; write++; } } return write; }};
/*Test cases:Solution sol;vector<int> nums1 = {3, 2, 2, 3};cout << sol.removeElement(nums1, 3) << endl; // 2
vector<int> nums2 = {0, 1, 2, 2, 3, 0, 4, 2};cout << sol.removeElement(nums2, 2) << endl; // 5
vector<int> nums3 = {2};cout << sol.removeElement(nums3, 3) << endl; // 1
vector<int> nums4 = {};cout << sol.removeElement(nums4, 0) << endl; // 0*//*Remove all occurrences of a value in-place from an array and return the new length.
Approach: Two PointersUse a 'write' pointer to place non-val elements and a 'read' pointer to scan the array.When read finds a non-val element, copy it to the write position and advance both.When read finds a val element, skip it and only advance read.
Time Complexity: O(n) — single pass through the arraySpace Complexity: O(1) — no extra data structures
Example 1:Input: nums = [3,2,2,3], val = 3Output: 2Array after: [2,2,_,_]Explanation: The first 2 elements are [2, 2]; elements after position 2 are ignored.
Example 2:Input: nums = [0,1,2,2,3,0,4,2], val = 2Output: 5Array after: [0,1,4,0,3,_,_,_]Explanation: The first 5 elements contain no 2.*/
class Solution { public int removeElement(int[] nums, int val) { int write = 0; for (int read = 0; read < nums.length; read++) { if (nums[read] != val) { nums[write] = nums[read]; write++; } } return write; }}
/*Test cases:Solution sol = new Solution();int[] nums1 = {3, 2, 2, 3};System.out.println(sol.removeElement(nums1, 3)); // 2
int[] nums2 = {0, 1, 2, 2, 3, 0, 4, 2};System.out.println(sol.removeElement(nums2, 2)); // 5
int[] nums3 = {2};System.out.println(sol.removeElement(nums3, 3)); // 1
int[] nums4 = {};System.out.println(sol.removeElement(nums4, 0)); // 0*//*Remove all occurrences of a value in-place from an array and return the new length.
Approach: Two PointersUse a 'write' pointer to place non-val elements and a 'read' pointer to scan the array.When read finds a non-val element, copy it to the write position and advance both.When read finds a val element, skip it and only advance read.
Time Complexity: O(n) — single pass through the arraySpace Complexity: O(1) — no extra data structures
Example 1:Input: nums = [3,2,2,3], val = 3Output: 2Array after: [2,2,_,_]Explanation: The first 2 elements are [2, 2]; elements after position 2 are ignored.
Example 2:Input: nums = [0,1,2,2,3,0,4,2], val = 2Output: 5Array after: [0,1,4,0,3,_,_,_]Explanation: The first 5 elements contain no 2.*/
/** * @param {number[]} nums * @param {number} val * @return {number} */function removeElement(nums, val) { let write = 0; for (let read = 0; read < nums.length; read++) { if (nums[read] !== val) { nums[write] = nums[read]; write++; } } return write;}
// Test casesconsole.log(removeElement([3, 2, 2, 3], 3)); // 2console.log(removeElement([0, 1, 2, 2, 3, 0, 4, 2], 2)); // 5console.log(removeElement([2], 3)); // 1console.log(removeElement([], 0)); // 0/*Remove all occurrences of a value in-place from an array and return the new length.
Approach: Two PointersUse a 'write' pointer to place non-val elements and a 'read' pointer to scan the array.When read finds a non-val element, copy it to the write position and advance both.When read finds a val element, skip it and only advance read.
Time Complexity: O(n) — single pass through the arraySpace Complexity: O(1) — no extra data structures
Example 1:Input: nums = [3,2,2,3], val = 3Output: 2Array after: [2,2,_,_]Explanation: The first 2 elements are [2, 2]; elements after position 2 are ignored.
Example 2:Input: nums = [0,1,2,2,3,0,4,2], val = 2Output: 5Array after: [0,1,4,0,3,_,_,_]Explanation: The first 5 elements contain no 2.*/
impl Solution { pub fn remove_element(nums: &mut Vec<i32>, val: i32) -> i32 { let mut write = 0; for read in 0..nums.len() { if nums[read] != val { nums[write] = nums[read]; write += 1; } } write as i32 }}
/*Test cases:let mut nums1 = vec![3, 2, 2, 3];assert_eq!(Solution::remove_element(&mut nums1, 3), 2);
let mut nums2 = vec![0, 1, 2, 2, 3, 0, 4, 2];assert_eq!(Solution::remove_element(&mut nums2, 2), 5);
let mut nums3 = vec![2];assert_eq!(Solution::remove_element(&mut nums3, 3), 1);
let mut nums4: Vec<i32> = vec![];assert_eq!(Solution::remove_element(&mut nums4, 0), 0);*//*Remove all occurrences of a value in-place from an array and return the new length.
Approach: Two PointersUse a 'write' pointer to place non-val elements and a 'read' pointer to scan the array.When read finds a non-val element, copy it to the write position and advance both.When read finds a val element, skip it and only advance read.
Time Complexity: O(n) — single pass through the arraySpace Complexity: O(1) — no extra data structures
Example 1:Input: nums = [3,2,2,3], val = 3Output: 2Array after: [2,2,_,_]Explanation: The first 2 elements are [2, 2]; elements after position 2 are ignored.
Example 2:Input: nums = [0,1,2,2,3,0,4,2], val = 2Output: 5Array after: [0,1,4,0,3,_,_,_]Explanation: The first 5 elements contain no 2.*/
func removeElement(nums []int, val int) int { write := 0 for read := 0; read < len(nums); read++ { if nums[read] != val { nums[write] = nums[read] write++ } } return write}
/*Test cases:nums1 := []int{3, 2, 2, 3}fmt.Println(removeElement(nums1, 3)) // 2
nums2 := []int{0, 1, 2, 2, 3, 0, 4, 2}fmt.Println(removeElement(nums2, 2)) // 5
nums3 := []int{2}fmt.Println(removeElement(nums3, 3)) // 1
nums4 := []int{}fmt.Println(removeElement(nums4, 0)) // 0*/Approach 2: Brute Force
Section titled “Approach 2: Brute Force”Scan the array from the beginning. When you find an element equal to val, remove it by shifting all subsequent elements left by one position. Repeat until no more elements equal val are found.
This approach is simple to understand but is inefficient because each removal triggers a shift operation that takes O(n) time.
Step-by-step Example
Section titled “Step-by-step Example”Input: nums = [3,2,2,3], val = 3
| Step | i | nums[i] | Action | Array State | Explanation |
|---|---|---|---|---|---|
| 0 | 0 | 3 | 3 == 3 → remove | [2,2,3] | Shift elements left, length 3 |
| 1 | 0 | 2 | 2 ≠ 3 → skip | [2,2,3] | Move to next element |
| 2 | 1 | 2 | 2 ≠ 3 → skip | [2,2,3] | Move to next element |
| 3 | 2 | 3 | 3 == 3 → remove | [2,2] | Shift elements left, length 2 |
| Done | — | — | — | [2,2] | Return 2 |
Final result: First 2 elements are [2, 2].
Pseudocode
Section titled “Pseudocode”function removeElementBruteForce(nums, val): i = 0 while i < len(nums): if nums[i] == val: remove nums[i] // Shift all elements after i one position left else: i++ return len(nums)Solution Code
Section titled “Solution Code”"""Remove all occurrences of a value in-place from an array and return the new length.
Approach: Brute ForceScan the array. When an element equals val, remove it by shifting all subsequent elementsleft by one position. Repeat until no more elements equal val are found.Do not increment the index after removal so the shifted elements are re-examined.
Time Complexity: O(n²) — worst case when all elements equal val, each removal is O(n)Space Complexity: O(1) — no extra data structures
Example 1:Input: nums = [3,2,2,3], val = 3Output: 2Array after: [2,2,_,_]Explanation: First 3 is removed, then second 3 is removed.
Example 2:Input: nums = [0,1,2,2,3,0,4,2], val = 2Output: 5Array after: [0,1,4,0,3,_,_,_]Explanation: Each 2 is removed by shifting subsequent elements left."""
from typing import List
def remove_element(nums: List[int], val: int) -> int: i = 0 while i < len(nums): if nums[i] == val: nums.pop(i) # Remove element and shift all elements after i one position left else: i += 1 return len(nums)
# Test casesprint(remove_element([3, 2, 2, 3], val=3)) # 2print(remove_element([0, 1, 2, 2, 3, 0, 4, 2], val=2)) # 5print(remove_element([2], val=3)) # 1print(remove_element([], val=0)) # 0#include <vector>using namespace std;
/*Remove all occurrences of a value in-place from an array and return the new length.
Approach: Brute ForceScan the array. When an element equals val, remove it by erasing it from the vector.This shifts all subsequent elements left by one position. Repeat until no more elementsequal val are found. Do not increment the index after removal.
Time Complexity: O(n²) — worst case when all elements equal val, each erase is O(n)Space Complexity: O(1) — no extra data structures beyond the input vector
Example 1:Input: nums = [3,2,2,3], val = 3Output: 2Array after: [2,2,_,_]Explanation: First 3 is removed, then second 3 is removed.
Example 2:Input: nums = [0,1,2,2,3,0,4,2], val = 2Output: 5Array after: [0,1,4,0,3,_,_,_]Explanation: Each 2 is removed by erasing and shifting subsequent elements left.*/
class Solution {public: int removeElement(vector<int>& nums, int val) { int i = 0; while (i < nums.size()) { if (nums[i] == val) { nums.erase(nums.begin() + i); // Remove element and shift all elements after i one position left } else { i++; } } return nums.size(); }};
/*Test cases:Solution sol;vector<int> nums1 = {3, 2, 2, 3};cout << sol.removeElement(nums1, 3) << endl; // 2
vector<int> nums2 = {0, 1, 2, 2, 3, 0, 4, 2};cout << sol.removeElement(nums2, 2) << endl; // 5
vector<int> nums3 = {2};cout << sol.removeElement(nums3, 3) << endl; // 1
vector<int> nums4 = {};cout << sol.removeElement(nums4, 0) << endl; // 0*//*Remove all occurrences of a value in-place from an array and return the new length.
Approach: Brute ForceScan the array. When an element equals val, shift all subsequent elements left by one position.This is implemented by copying elements and tracking the new length. Do not increment theindex after removing so shifted elements are re-examined.
Time Complexity: O(n²) — worst case when all elements equal val, each shift is O(n)Space Complexity: O(1) — no extra data structures beyond the input array
Example 1:Input: nums = [3,2,2,3], val = 3Output: 2Array after: [2,2,_,_]Explanation: First 3 is removed, then second 3 is removed.
Example 2:Input: nums = [0,1,2,2,3,0,4,2], val = 2Output: 5Array after: [0,1,4,0,3,_,_,_]Explanation: Each 2 is removed by shifting subsequent elements left.*/
class Solution { public int removeElement(int[] nums, int val) { int length = nums.length; int i = 0; while (i < length) { if (nums[i] == val) { // Shift all elements after i one position left for (int j = i; j < length - 1; j++) { nums[j] = nums[j + 1]; } length--; // Decrease length instead of removing from array } else { i++; } } return length; }}
/*Test cases:Solution sol = new Solution();int[] nums1 = {3, 2, 2, 3};System.out.println(sol.removeElement(nums1, 3)); // 2
int[] nums2 = {0, 1, 2, 2, 3, 0, 4, 2};System.out.println(sol.removeElement(nums2, 2)); // 5
int[] nums3 = {2};System.out.println(sol.removeElement(nums3, 3)); // 1
int[] nums4 = {};System.out.println(sol.removeElement(nums4, 0)); // 0*//*Remove all occurrences of a value in-place from an array and return the new length.
Approach: Brute ForceScan the array. When an element equals val, remove it using splice() which shifts allsubsequent elements left by one position. Do not increment the index after removal soshifted elements are re-examined.
Time Complexity: O(n²) — worst case when all elements equal val, each splice is O(n)Space Complexity: O(1) — no extra data structures beyond the input array
Example 1:Input: nums = [3,2,2,3], val = 3Output: 2Array after: [2,2,_,_]Explanation: First 3 is removed, then second 3 is removed.
Example 2:Input: nums = [0,1,2,2,3,0,4,2], val = 2Output: 5Array after: [0,1,4,0,3,_,_,_]Explanation: Each 2 is removed by splicing and shifting subsequent elements left.*/
/** * @param {number[]} nums * @param {number} val * @return {number} */function removeElement(nums, val) { let i = 0; while (i < nums.length) { if (nums[i] === val) { nums.splice(i, 1); // Remove element at index i and shift all elements after i one position left } else { i++; } } return nums.length;}
// Test casesconsole.log(removeElement([3, 2, 2, 3], 3)); // 2console.log(removeElement([0, 1, 2, 2, 3, 0, 4, 2], 2)); // 5console.log(removeElement([2], 3)); // 1console.log(removeElement([], 0)); // 0/*Remove all occurrences of a value in-place from an array and return the new length.
Approach: Brute ForceScan the array. When an element equals val, remove it using remove() which shifts allsubsequent elements left by one position. Do not increment the index after removal soshifted elements are re-examined.
Time Complexity: O(n²) — worst case when all elements equal val, each remove is O(n)Space Complexity: O(1) — no extra data structures beyond the input vector
Example 1:Input: nums = [3,2,2,3], val = 3Output: 2Array after: [2,2,_,_]Explanation: First 3 is removed, then second 3 is removed.
Example 2:Input: nums = [0,1,2,2,3,0,4,2], val = 2Output: 5Array after: [0,1,4,0,3,_,_,_]Explanation: Each 2 is removed by removing and shifting subsequent elements left.*/
impl Solution { pub fn remove_element(nums: &mut Vec<i32>, val: i32) -> i32 { let mut i = 0; while i < nums.len() { if nums[i] == val { nums.remove(i); // Remove element at index i and shift all elements after i one position left } else { i += 1; } } nums.len() as i32 }}
/*Test cases:let mut nums1 = vec![3, 2, 2, 3];assert_eq!(Solution::remove_element(&mut nums1, 3), 2);
let mut nums2 = vec![0, 1, 2, 2, 3, 0, 4, 2];assert_eq!(Solution::remove_element(&mut nums2, 2), 5);
let mut nums3 = vec![2];assert_eq!(Solution::remove_element(&mut nums3, 3), 1);
let mut nums4: Vec<i32> = vec![];assert_eq!(Solution::remove_element(&mut nums4, 0), 0);*//*Remove all occurrences of a value in-place from an array and return the new length.
Approach: Brute ForceScan the array. When an element equals val, remove it by slicing out that element,which shifts all subsequent elements left by one position. Do not increment the indexafter removal so shifted elements are re-examined.
Time Complexity: O(n²) — worst case when all elements equal val, each removal is O(n)Space Complexity: O(1) — no extra data structures beyond the input slice
Example 1:Input: nums = [3,2,2,3], val = 3Output: 2Array after: [2,2,_,_]Explanation: First 3 is removed, then second 3 is removed.
Example 2:Input: nums = [0,1,2,2,3,0,4,2], val = 2Output: 5Array after: [0,1,4,0,3,_,_,_]Explanation: Each 2 is removed by slicing and shifting subsequent elements left.*/
func removeElement(nums []int, val int) int { i := 0 for i < len(nums) { if nums[i] == val { // Remove element at index i by slicing: append elements before i with elements after i nums = append(nums[:i], nums[i+1:]...) } else { i++ } } return len(nums)}
/*Test cases:nums1 := []int{3, 2, 2, 3}fmt.Println(removeElement(nums1, 3)) // 2
nums2 := []int{0, 1, 2, 2, 3, 0, 4, 2}fmt.Println(removeElement(nums2, 2)) // 5
nums3 := []int{2}fmt.Println(removeElement(nums3, 3)) // 1
nums4 := []int{}fmt.Println(removeElement(nums4, 0)) // 0*/Common mistakes
Section titled “Common mistakes”Approach 3: Optimized Two-Pointer
Section titled “Approach 3: Optimized Two-Pointer”A third approach demonstrating an alternative technique for solving this problem. This implementation optimizes either time or space complexity compared to the previous approaches.
Pseudocode
Section titled “Pseudocode”function approach3(): // Implementation approach goes hereSolution Code
Section titled “Solution Code”"""Solution for Remove Element"""
def solve(): """Implementation for approach 3 of Remove Element""" pass
if __name__ == "__main__": print("Solution ready")#include <bits/stdc++.h>using namespace std;
// Solution for Remove Element// Approach 3: Implementation
int main() {{ // Main implementation goes here return 0;}}/** * Solution for Remove Element * Approach 3 */public class RemoveElementOptimized {{
public static void main(String[] args) {{ // Implementation goes here }}}}/** * Solution for Remove Element * Approach 3 */
function solve() {{ // Implementation goes here}}
module.exports = solve;/// Solution for Remove Element/// Approach 3
fn main() {{ println!("Solution implementation");}}package main
import "fmt"
// Solution for Remove Element// Approach 3
func main() {{ fmt.Println("Solution implementation")}}