✅ 链表相关的题目,尤其是涉及到【增删改操作】最关键是要理解虚拟头结点的使用技巧。复习时可做一下【2.设计链表】,进行全面的思考和回顾。
而一些环形链表、公共节点问题,更多像是数学问题。
1.移除链表元素
题目链接
✅ 关于循环退出的条件是 while(cur.next!=null) or while(cur!=null):
(1)对于插入或删除操作,通常需要找到特定元素的前一个元素。用while(cur.next!=null) ,可以在循环内部检查当前节点的下一个节点cur.next是否是目标节点,然后对当前节点cur进行操作。
(2)可以按循环结束时刻来思考,即你希望循环结束时指针指向最后一个元素还是null。
✅不管任何时候写到ptr.next/ptr.val时,都要想一下是否判断过ptr!=null。
*/
class Solution {
public ListNode removeElements(ListNode head, int val) {
ListNode dummy=new ListNode(0,head);
ListNode cur=dummy;
while(cur.next!=null){
if(cur.next.val==val){
cur.next=cur.next.next;
}
else{
cur=cur.next;
}
}
return dummy.next;
}
}
2.设计链表
✅ 在Java中,当定义一个类并创建对象时,如果属性没有显式地初始化,那么基本数据类型(如int)会被赋予默认值(int的默认值是0),而引用类型(如ListNode)的默认值是null。
所以想让ListNode的next属性为null,无需显式赋值。
题目链接
class ListNode{
int val;
ListNode next;
public ListNode(){ }
public ListNode(int val){ this.val=val;}
public ListNode(int val, ListNode next ){ this.val=val; this.next=next;}
}
class MyLinkedList {
//虚拟头节点
ListNode head;
int size;
public MyLinkedList() {
head = new ListNode(0);
size=0;
}
public int get(int index) {
if( index<0 || index>size-1){
return -1;
}
ListNode cur=this.head;
for(int i=0;i<=index;i++){
cur=cur.next;
}
return cur.val;
}
public void addAtHead(int val) {
ListNode node=new ListNode(val);
node.next=head.next;
head.next=node;
size++;
}
public void addAtTail(int val) {
ListNode node=head;
while(node.next!=null){
node=node.next;
}
node.next=new ListNode(val);
size++;
}
public void addAtIndex(int index, int val) {
if( index<0 || index>size){
return;
}
ListNode node=head;
for(int i=0;i<index;i++){
node=node.next;
}
ListNode newNode=new ListNode(val);
newNode.next= node.next;
node.next=newNode;
size++;
}
public void deleteAtIndex(int index) {
if(index<0 || index>size-1){
return;
}
ListNode node=head;
for(int i=0;i<index;i++){
node=node.next;
}
node.next=node.next.next;
size--;
}
}
3 .反转链表
在链表反转过程中,如果只使用一个指针,很容易在更新next指针之前丢失对下一个节点的引用,导致无法继续遍历链表,使用两个指针可以避免这种情况。
class Solution {
public ListNode reverseList(ListNode head) {
ListNode cur=head;
ListNode pre=null;
while(cur!=null){
ListNode next=cur.next;
cur.next=pre;
pre=cur;
cur=next;
}
return pre;
}
}