Here's my solution. Maybe it looks a little complicated and unnecessary. I passed 105/111 tests, so I wanted to find where the bug is in my code. Here you can direct to the Leetcode page. Remove Element
pub fn remove_element(nums: &mut Vec<i32>, val: i32) -> i32 {
let mut temp = Vec::new();
let len = nums.len();
for (i, v) in nums.iter().enumerate() {
if *v == val {
temp.push(i)
}
}
let new_len = temp.len();
temp.iter()
.skip_while(|x| (len - new_len..len).contains(x))
.zip((len - new_len..len).skip_while(|x| temp.contains(x)))
.map(|(a, b)| {
nums[*a] = nums[b];
})
.collect::<()>();
(len - new_len) as i32
}
My idea is to create a vec temp
which stores the indexs of the elements that equal to the val
, which is to be deleted.
Then I use functional programming. The brief idea is to set the end of the nums as swap area with length of the temp.len()
. Then I swap all the values that don't equal to the value
to the front with the indexs stored in temp
(undoubtedly we need to omit the indexs that is already in the swap area)
Here is the error testcase:
# Testcase:
[4,2,0,2,2,1,4,4,1,4,3,2]
# Answer:
[3,2,0,2,2,1,4,1]
# Expected:
[2,2,0,2,2,1,3,1]
Maybe you should test this code in the leetcode yourself. Thanks a lot!
I found that I should use filter
instead of skip_while
, that's where the problem is.
pub fn remove_element(nums: &mut Vec<i32>, val: i32) -> i32 {
let mut temp = Vec::new();
let len = nums.len();
for (i, v) in nums.iter().enumerate() {
if *v == val {
temp.push(i)
}
}
let new_len = temp.len();
temp.sort_by(|a, b| b.cmp(a));
temp.iter()
.skip_while(|x| (len - new_len..len).contains(x))
.zip((len - new_len..len).filter(|x| !temp.contains(x)))
.for_each(|(a, b)| {
println!("{a} : {b}");
nums[*a] = nums[b]
});
(len - new_len) as i32
}