203. 移除链表元素
题目描述
给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
解题思路
链表题,hhhh,不是特别想用rust,不多说,直接操作ownersheip
#![allow(unused)] fn main() { struct Solution {} // Definition for singly-linked list. #[derive(PartialEq, Eq, Clone, Debug)] pub struct ListNode { pub val: i32, pub next: Option<Box<ListNode>> } impl ListNode { #[inline] fn new(val: i32) -> Self { ListNode { next: None, val } } } impl Solution { pub fn remove_elements(head: Option<Box<ListNode>>, val: i32) -> Option<Box<ListNode>> { let mut head = Some(Box::new(ListNode { val: 0, next: head })); let mut a: &mut Option<Box<ListNode>> = &mut head; while a.as_deref_mut().unwrap().next.is_some() { // ^ Option<&mut ListNode> // let v = a.as_deref_mut().unwrap().next.as_deref().unwrap().val; if v == val { let mut b = a.as_deref_mut().unwrap().next.take(); let c = b.as_deref_mut().unwrap().next.take(); a.as_deref_mut().unwrap().next = c; } else { let b = &mut a.as_deref_mut().unwrap().next; a = b; } } head.unwrap().next } } }
属实有点恶心了,看着太复杂了,这就是不用take的后果
学习感想
#![allow(unused)] fn main() { struct Solution {} // Definition for singly-linked list. #[derive(PartialEq, Eq, Clone, Debug)] pub struct ListNode { pub val: i32, pub next: Option<Box<ListNode>> } impl ListNode { #[inline] fn new(val: i32) -> Self { ListNode { next: None, val } } } impl Solution { pub fn remove_elements(head: Option<Box<ListNode>>, val: i32) -> Option<Box<ListNode>> { let mut dummyHead = Box::new(ListNode::new(0)); dummyHead.next = head; let mut cur: &mut ListNode = dummyHead.as_mut(); // 使用take()替换std::men::replace(&mut node.next, None)达到相同的效果,并且更普遍易读 while let Some(nxt) = cur.next.take() { if nxt.val == val { cur.next = nxt.next; } else { cur.next = Some(nxt); cur = cur.next.as_mut().unwrap(); // coercion // ^ Option<Box<ListNode>> // ^ Option<&mut Box<ListNode>> // ^ &mut Box<ListNode> // deref coerce -> & mut ListNode } } dummyHead.next } } }
向这位老哥学习,使用take,管它用不用,先取下来再说。并且 先把option刨了
#![allow(unused)] fn main() { struct Solution {} // Definition for singly-linked list. #[derive(PartialEq, Eq, Clone, Debug)] pub struct ListNode { pub val: i32, pub next: Option<Box<ListNode>> } impl ListNode { #[inline] fn new(val: i32) -> Self { ListNode { next: None, val } } } impl Solution { pub fn remove_elements(mut head: Option<Box<ListNode>>, val: i32) -> Option<Box<ListNode>> { let mut res: Option<Box<ListNode>> = None; let mut ptr: &mut Option<Box<ListNode>> = &mut res; while let Some(mut x) = head { head = x.next.take(); if x.val != val { *ptr = Some(x); ptr = &mut ptr.as_mut().unwrap().next; } } res } } }
链表的ownership还是非常容易理清楚的
一个Option不是owner没法直接unwrap,但是as_mut了之后可以随意unwrap,这也是容器穿透