原贴地址:http://blog.leanote.com/post/dawnmagnet/lc203
题目
给你一个链表的头节点 head
和一个整数 val
,请你删除链表中所有满足 Node.val == val
的节点,并返回 新的头节点 。
示例 1:

输入:head = [1,2,6,3,4,5,6], val = 6 输出:[1,2,3,4,5]
示例 2:
输入:head = [], val = 1 输出:[]
示例 3:
输入:head = [7,7,7,7], val = 7 输出:[]
提示:
- 列表中的节点在范围
[0, 104]
内 1 <= Node.val <= 50
0 <= k <= 50
思路分析
本题的难点就在于对链表的操作,如果这个链表是一个形式如示例3的链表,删除完之后可能会连原先的head节点都会被删除,但是如果我们捏着head不放,根本就没法删head,怎么办呢。
这里就会说到一个常用的做链表题的手段了,就是添加watch节点。
原来是7->7->7->7->null
添加了watch之后 变成了watch->7->7->7->7->null
这样操作以后,我们就不用担心对之前的head节点做什么操作了,因为head已经变成了一个普通的节点,无需顾虑。操作完之后,我们不返回之前的head,因为head可能已经不知道去哪儿了。所以我们返回watch->next即可,不管这个链表处理完是什么样,watch都不会对链表的操作产生影响,这也是为什么它叫watch,因为它只是起一个辅助作用。
C++代码
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode * watch = new ListNode(0);
watch->next = head;
ListNode* cur = watch;
while (cur->next) {
if (cur->next->val == val) {
cur->next = cur->next->next;
} else {
cur = cur->next;
}
}
return watch->next;
}
};
Rust代码
impl Solution {
pub fn remove_elements(head: Option<Box<ListNode>>, val: i32) -> Option<Box<ListNode>> {
let mut watch = ListNode { val: 0, next: head };
let mut pre = &mut watch;
while let Some(ref mut node) = pre.next {
if node.val == val {
pre.next = node.next.take();
} else {
pre = pre.next.as_mut().unwrap();
}
}
watch.next
}
}