Home > Net >  Delete duplicated in a linked list solution from C to rust
Delete duplicated in a linked list solution from C to rust

Time:11-19

I have this code solution written in c for the problem remove-duplicates-from-sorted-list and just now I'm learning rust and I want to build the same solution in rust programming language my rust linkedList doesn't have ListNode have Option<Box<Node>>

class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        if (!head) return head;

        ListNode* current = head;
        while (current->next) {
            if (current->next->val == current->val)
                current->next = current->next->next;
            else 
                current = current->next;
        }
        return head;
    }
};

I don't want change my approach to solve this problem because any algorithm can be written in any programming language maybe the different words but the steps perform by the computer will be the same.

I can't write my validation for my while (current->next) without unwrap current.unwrap().next and if current is None this throw a panic.

and same here current->next = current->next->next; where my first idea was current.unwrap().next = current.unwrap().next.unwrap().next;

I try to read in rust documentation about Option and match pattern and how use Some while for my case but I can't find any example similar.

I only can traverse my Single linkedList without modify my head pointer and lost data like this code.

    pub fn delete_duplicates(head: Option<Box<ListNode>>) -> Option<Box<ListNode>> {
        if head.is_none() {
            return head
        };
    
        let mut current = &head;
    
        while let Some(node) = current {
            current = &node.next;
        }
        head
    }

If you know the rust way for write my c solution please share it with me and thank you for your help.

CodePudding user response:

impl Solution {
    pub fn delete_duplicates(mut head: Option<Box<ListNode>>) -> Option<Box<ListNode>> {

by matching instead of just checking for .is_none() we can get the value inside & check for None at the same time.

        // if (!head) return head;
        // ListNode* current = head;
        let mut current = match head.as_mut() {
            Some(c) => c,
            None => return head,
        };

Then we take the next item while checking it's there. By using .take() we avoid having 2 mutable borrows of current, we'll also clean up the memory this way.

        // while (current->next) {
        while let Some(mut rest) = current.next.take() {
            // if (current->next->val == current->val)
            if rest.val == current.val {
                // current->next = current->next->next;
                current.next = rest.next;
            } else {
                // since we took earlier we gotta put it back
                current.next = Some(rest);
                // current = current->next;
                // unwrap is perfectly fine since we just set it to Some(rest)
                current = current.next.as_mut().unwrap();
            }
        }
        return head;
    }
}

.as_mut() is just a way to turn a &mut Option<T> into Option<&mut T>

  • Related