题目
难度简单500
删除链表中等于给定值 *val* 的所有节点。
示例:
输入: 1->2->6->3->4->5->6, val = 6
输出: 1->2->3->4->5
分析
我们可以生成一个新的链表,新的链表中不包含移除的元素即可。
如上图,我们需要遍历原有的列表上的Node,如果不是要移除的结点,就添加到新链表最后一个节点的next上。
解法一
-
如何遍历链表
while(head!=null){ head=head.next; } -
记录新链表的head和新链表的最后一个节点的位置
ListNode newHead=null; ListNode currentNode=null; -
如果变量到的结点不是要移除的结点,就将他添加到新链表上。然后移动currentNode指向最后一个节点。
if(head.val!=val){ currentNode.next=head; currentNode=head; } -
最后需要注意将最后一个节点的next设置为null,来结束当前链表。
currentNode.next=null;
下面是全部的代码:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode removeElements(ListNode head, int val) {
if (head == null) return null;
//记录新链表的头
ListNode newHead = null;
//记录当前扫描到的Node位置
ListNode currentNode = null;
while (head != null) {
if (val != head.val) {
if (currentNode == null) {
//生成新链表头
newHead = head;
//记录新Node的位置
currentNode = head;
} else {
//链表上添加新Node
currentNode.next = head;
//记录新Node的位置
currentNode = head;
}
}
head = head.next;
}
//注意空指针
if (currentNode == null) {
return null;
} else {
//结束链表,currentNode就是链表的尾部
currentNode.next = null;
}
return newHead;
}
}
提交结果:
解法二
使用虚拟节点,减少判断。
直接新建一个节点作为虚拟节点VNode,如果有符合条件的Node,直接添加到该VNode的next上。
最后返回的新链表的head,其实就是虚拟节点的next位置的Node。
这样我们就不必判断头节点是否为空。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode removeElements(ListNode head, int val) {
if (head == null) return null;
//虚拟节点
ListNode vNode = new ListNode(0);
//记录当前扫描到的Node位置
ListNode currentNodex = vNode;
while (head != null) {
if (val != head.val) {
currentNodex.next = head;
currentNodex = head;
}
head = head.next;
}
currentNodex.next = null;
//虚拟节点的next就是新链表的head
return vNode.next;
}
}
效率上应该没有什么提升,只是间接了思路。