
Let’s create a simple Rust solution for this LeetCode problem. The key idea is to keep track of how many times we’ve seen each number and only include it in the result if it appears twice or less, all while modifying the array in-place.
Table of Contents
Leetcode problem : 80. Remove Duplicates from Sorted Array II
Given an integer array nums sorted in non-decreasing order, remove some duplicates in-place such that each unique element appears at most twice. The relative order of the elements should be kept the same.
Since it is impossible to change the length of the array in some languages, you must instead have the result be placed in the first part of the array nums. More formally, if there are k elements after removing the duplicates, then the first k elements of nums should hold the final result. It does not matter what you leave beyond the first k elements.
Return k after placing the final result in the first k slots of nums.
Do not allocate extra space for another array. You must do this by modifying the input array in-place with O(1) extra memory.
Custom Judge:
The judge will test your solution with the following code:
int[] nums = […]; // Input array
int[] expectedNums = […]; // The expected answer with correct length
int k = removeDuplicates(nums); // Calls your implementation
assert k == expectedNums.length;
for (int i = 0; i < k; i++) {
assert nums[i] == expectedNums[i];
}
If all assertions pass, then your solution will be accepted.
Here’s a straightforward solution:
impl Solution {
pub fn remove_duplicates(nums: &mut Vec<i32>) -> i32 {
if nums.len() <= 2 {
return nums.len() as i32;
}
// Position to place the next valid number
let mut k = 2;
// Start from 3rd element
for i in 2..nums.len() {
// If current number is different from number two positions back,
// we can include it
if nums[i] != nums[k - 2] {
nums[k] = nums[i];
k += 1;
}
}
k as i32
}
}
Explain every Line of code :
Let’s go through the Rust solution line by line and explain each part in detail:
impl Solution {
- This starts the implementation block for a Solution struct (typically provided by LeetCode)
- Everything inside this block is part of our solution
pub fn remove_duplicates(nums: &mut Vec<i32>) -> i32 {
- Defines a public function called remove_duplicates
- Takes a mutable reference to a vector of 32-bit integers (&mut Vec<i32>)
- Returns a 32-bit integer (i32) representing the new length k
- The &mut means we can modify the input vector in-place
if nums.len() <= 2 {
- Checks if the length of the input array is 2 or less
- This is our base case – if true, we don’t need to remove anything
return nums.len() as i32;
- If length ≤ 2, return the length cast to i32
- We use as i32 to convert from usize (returned by len()) to i32
- Since we allow up to 2 duplicates, arrays of length 0, 1, or 2 are unchanged
}
- Closes the if block
let mut k = 2;
- Declares a mutable variable k initialized to 2
- k represents where we’ll place the next valid number
- Starts at 2 because first two elements are always kept (indices 0 and 1)
for i in 2..nums.len() {
- Starts a loop from index 2 to the end of the array
- 2..nums.len() is a range from 2 (inclusive) to nums.len() (exclusive)
- i is the current position we’re examining in the input array
if nums[i] != nums[k - 2] {
- Compares current number with number two positions back from k
- nums[i] is the current number we’re considering
- nums[k – 2] is the number two slots before our current placement position
- If they’re different, we can include the current number
nums[k] = nums[i];
- If the condition is true, copy the current number to position k
- This places the number in the next available result slot
k += 1;
- Increment k to point to the next available position
- We only increment when we actually place a number
}
- Closes the if block
}
- Closes the for loop
k as i32
- Returns k cast to i32 as required by the function signature
- At this point, k represents the length of the valid result
- The first k elements of nums contain our answer
}
- Closes the function definition
}
- Closes the implementation block
Let’s see it with an example: nums = [1,1,1,2,2,3]:
- len() = 6 > 2, so skip base case
- k = 2
- i = 2: nums[2]=1 == nums[0]=1, skip
- i = 3: nums[3]=2 != nums[0]=1, nums[2]=2, k=3
- i = 4: nums[4]=2 != nums[1]=1, nums[3]=2, k=4
- i = 5: nums[5]=3 != nums[2]=2, nums[4]=3, k=5
- Return 5, array becomes [1,1,2,2,3,3] (last 3 doesn’t matter)
Each line works together to:
- Handle small arrays immediately
- Track our placement position (k)
- Check each number against the one two positions back
- Place valid numbers in the result portion
- Return the final length