一、移除链表元素
移除链表元素的关键点在于如何建立辅助指针帮助我们完成元素的删除。
如果我们不建立辅助指针,试想一下,要想完成链表的删除,我们需要将待删除节点的next指向空,但是这样会导致之前的链表全部丢失,因此我们肯定需要一个辅助节点,来指向待删除节点的前一个节点,这样才能通过前一个节点的next直接指向待删除节点的next节点来跳过待删除节点,使得整个链表保持完整,同时删除待删除节点。
代码实现
public ListNode removeElements(ListNode head, int val) {
if(head == null){
return null;
}
ListNode newList = new ListNode(-1);//赋值-1是因为题目给出了节点的val范围在1-50之间,因此给其赋一个没有意义的值当做头结点。
ListNode pre = newList;//新建一个pre指向head节点的前一个节点,方便我们进行删除操作。
pre.next = head;
while(head != null){//只要当前节点不为零,就继续遍历
if(head.val == val){ //当前节点为待删除节点
pre.next = head.next;
head = head.next;
}
else{//当前节点不是待删除节点,则我们将节点向后移动
pre = pre.next;
head = head.next;
}
}
return newList.next;
}
二、反转链表
同样,对于链表一类的操作,很关键的问题就是如何创建辅助指针来帮助我们完成操作。
显然,要实现反转链表,我们需要将当前节点的next指向其前一位节点,因此我们需要一个辅助指针pre来指向其前一个节点。
那么,实现链表反转的操作就是:
1.将head的next指向前一个节点prev
2.将prev指向当前的head
3.将head指向head的下一个节点head.next
但是上面存在一个问题,我们在第一步中已经改变了head.next指向,导致head与原本的head.next失去关联了。
因此,我们需要新增加一个辅助指针next来指向原本的head.next节点,帮助链表的连续。
代码实现
public ListNode reverseList(ListNode head) {
//我们需要记住当前节点的前一个节点,同时还需要记住当前节点的后一个节点,因为需要反转,如果不记住后一个节点就会导致链表的丢失
//前一个节点
ListNode pre = null;
if(head == null || head.next == null){
return head;
}
while(head != null){
/*
只要当前节点不为null,进行反转操作,具体步骤如下:
1.将当前节点的next指向pre节点。
2.将pre节点更新为head节点
3.将head节点更新为head.next节点
这里有个问题,由于head的next在1中指向了pre,所以我们需要一个新的节点来记录head.next节点,这就是next节点的意义
*/
ListNode next = head.next;
head.next = pre;
pre = head;
head = next;
}
return pre;
}