题目
方法有多种,针对单链表的操作,这里只写两种比较好理解的:
第1种:
借助两个指针:pre 和 temp
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode() {} * ListNode(int val) { this.val = val; } * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { public ListNode removeElements(ListNode head, int val) { //1.避免第一种情况:头部为需要删除的元素 while(head!=null && head.val==val){ head=head.next; } //2.避免第2种情况:空链表或在第1步操作后链表为空 if(head==null){ return null; } //3.避免第三中情况:中间含有需要删除的元素 ListNode temp=head; ListNode pre = head; while(temp.next!=null){//注意:最后一个元素需要专门拎出来考虑,因为遍历到最后一个元素时,它的next指针为空,进入不了下一次while循环 if(temp.val==val){ pre.next = temp.next;//删除的核心代码 }else{//else很重要 pre=temp;//更新指针pre } temp=temp.next; } //情况4:最后一个元素是要删除的元素 if(temp.val==val){ pre.next = null;//让pre.next等于temp.next也可以,反正temp.next不存在,默认为null } return head; } }
第2种:
借助一个指针 pre
class Solution { public ListNode removeElements(ListNode head, int val) { //删除值相同的头结点后,可能新的头结点也值相等,用循环解决 while(head!=null&&head.val==val){ head=head.next; } if(head==null) return head; ListNode prev=head; //确保当前结点后还有结点 while(prev.next!=null){ if(prev.next.val==val){ prev.next=prev.next.next;//删除核心代码 }else{ prev=prev.next;//更新指针pre } } return head; } }
比较两种解决方法:
第一种题解:
temp指向当前元素,pre指向前一个元素
删除操作:pre.next=temp.next
如果不需要删除,就更新指针:pre=temp; 让pre等于temp
更新temp:temp=temp.next;
第二种题解:
pre始终指向前一个元素
删除操作:pre.next=pre.next.next
如果不需要删除,就更新指针:pre=pre.next;
区别:题解1因为引入了两个变量,所以比题解2多了更新temp的操作,但删除的思想是一样的。