Search code examples
algorithmrustdata-structuresfunctional-programming

Leetcode Rust 27 Remove Element


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!


Solution

  • 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
        }