203. 删除链表中的节点
删除链表中等于给定值 val 的所有节点。
示例:
输入: 1->2->6->3->4->5->6, val = 6
输出: 1->2->3->4->5
先贴上代码
/**
* 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) {
/**头节点的值也要被删除的时候(head.val == val),我们不能简单的直接将head保存起来,要把链表前面连续的需要删除的节点 从链表移除出去,得到一个头节点不需要* * 被删除的新链表(head.val != val)。
* 也就是第1个过程所做的事情。
**/
if(head==null)
return null;
while(head!=null&&head.val==val)//(过程1)
head=head.next;
if (head == null)//这里需要再做一次非空校验,例如输入[1,1,1] ,1; 链表全是1,执行过程(1)后,新链表为空,直接返回null即可。
return null;
ListNode temp = head;//头节点的val不等于va时
if(temp.next==null){
return temp;
}else{
while(temp.next!=null){
if(temp.next.val!=val){
temp=temp.next;
}else {
temp.next=temp.next.next;
}
}
}return head;
}
}
说明:1)头节点也要删除的情形没有考虑到,参考了https://blog.csdn.net/hocsoul/article/details/80151552,写的非常详细。
头节点的值也要被删除的时候(head.val == val),我们不能简单的直接将head保存起来,
要把链表前面连续的需要删除的节点 从链表移除出去,得到一个头节点不需要* * 被
删除的新链表(head.val != val)。
if(head==null)
return null;
while(head!=null&&head.val==val)//(过程1)
head=head.next;
头节点的值也要被删除的时候(head.val == val),我们不能简单的直接将head保存起来,要把链表前面连续的需要删除的节点 从链表移除出去,得到一个头节点不需要* * 被删除的新链表(head.val != val)。
2)非空校验,这点也容易忽略,就是对head进行替换后,可能出现新链表为空,直接返回null即可;
if (head == null)
return null;
3)不希望头节点head变化的话,最好先设置一个零时变量temp,本题中过程1需要改变head,故一开始不需要设置临时变量temp。
一般情况下,删除链表的代码:
故代码第三段:
ListNode temp = head;//头节点的val不等于va时
if(temp.next==null){
return temp;
}else{
while(temp.next!=null){
if(temp.next.val!=val){
temp=temp.next;
}else {
temp.next=temp.next.next;
}
}
}return head;
例子:
定义Node 以及printLinkedList
package testPro;
public class Node {
private final int value;
private Node next=null;
public Node(int value){
this.value=value;
this.next=null;//构造函数默认指向null
}
public int getValue() {
return value;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
/**
* 打印链表的值
* @param head
*/
public static void printLinkedList(Node head){
while(head!=null){
System.out.print(head.getValue());
System.out.print(" ");
head=head.getNext();
}
System.out.println();
}
}
注意两个节点值相等的情况:
通过设置下一个节点的形式
Node prev=head;
while(prev.getNext()!=null){
if(prev.getNext().getValue()==value){
//delete it
prev.setNext(prev.getNext().getNext());
}else{
prev=prev.getNext();
}
}
测试例子:
package testPro;
import java.util.Arrays;
public class LinkedistDeletor {
public static Node deleteIfEquals(Node head, int value){
//Loop invariant :List node form head up to prev has been
// processed.(Node with values equal to value are deleted.)
if(head==null)
return null;
while( head!=null &&head.getValue()==value){//循环处理头节点
head=head.getNext();
}
Node prev=head;
while(prev.getNext()!=null){
if(prev.getNext().getValue()==value){
//delete it
prev.setNext(prev.getNext().getNext());
}else{
prev=prev.getNext();
}
}
return head;//而不是return prev 因为prev 节点一直在移动,不是链表的头节点
}
public static void main(String[] args) {
LinkedListCreator creator=new LinkedListCreator();
LinkedistDeletor deletor=new LinkedistDeletor();
Node.printLinkedList(
deletor.deleteIfEquals( creator.createLinkedList(Arrays.asList(1,2,3,2,5)),2)
);
Node.printLinkedList(
deletor.deleteIfEquals( creator.createLinkedList(Arrays.asList(1,2,3,2,2)),2)
);
Node.printLinkedList(
deletor.deleteIfEquals( creator.createLinkedList(Arrays.asList(1,2,3,2,2)),1)
);
}
}