例题1移除链表的指定元素
203. 移除链表元素 - 力扣(LeetCode) (leetcode-cn.com)
头部的处理和后续的处理有不同,所以有两种处理方式;
方式一先处理头部
while(head!=null && head.val==val){
head=head.next;
}
if(head==null) return head; //头结点为空直接结束
方式二加入一个新的头结点,统一处理
if (head == null) {
return head;
}
// 因为删除可能涉及到头节点,所以设置dummy节点,统一操作
ListNode dummy = new ListNode(-1, head);
之后的处理就大致相同,设置两个结点,pre和cur结点
ListNode pre=head;
ListNode cur=head.next; //设置两个结点,当前结点和前结点
while(cur!=null){
if(cur.val==val){
cur=cur.next;
pre.next=cur;
}else{
pre=cur;
cur=cur.next;
}
}
return head;
例题2删除倒数第n个结点
19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode) (leetcode-cn.com)
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode pre=head;
ListNode cur=head; //维持两个指针
if(pre.next==null) return null; //处理特殊情况,仅有一个结点,删除后为空
for(int i=0;i<n;i++){
pre=pre.next; //使两个指针保持n的距离
}
if(pre==null) return head.next; //处理特殊情况,要删除的结点位于头部
while(pre.next!=null){
pre=pre.next;
cur=cur.next; //向后移动,使pre移动到链表的尾部
}
cur.next=cur.next.next; //删除倒数第n个结点
return head;
}
例题3链表相交
面试题 02.07. 链表相交 - 力扣(LeetCode) (leetcode-cn.com)
此题的关键是找出最长的那个链表,并使指针指向最短的链表的位置
基本思路是两个指针长度对齐,同时向后移动
如果两个指针相同,则返回该结点
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode cura=headA;
ListNode curb=headB;
int counta=0;
int countb=0;
while(cura!=null){
cura=cura.next;
counta++;
}
while(curb!=null){
curb=curb.next;
countb++; //分别计算出链表A和链表B的长度
}
cura=headA;
curb=headB;
if(counta>countb){
for(int i=0;i<counta-countb;i++){
cura=cura.next;
}
}else{
for(int i=0;i<countb-counta;i++){
curb=curb.next; //链表对齐
}
}
while(cura!=null){
if(cura==curb) return cura; //如果指针相同直接返回结点
cura=cura.next;
curb=curb.next;
}
return null; //没有交点返回null
}
例题4面试经典问题翻转链表
此题的解题思路是使用两个指针pre和cur遍历一遍链表
pre.next=cur,在此之前为防止pre的后续丢失,需要先用temp接收pre.next
public ListNode reverseList(ListNode head) {
if(head==null) return null; //首先判断是否为空,为空直接返回
ListNode pre=head.next;
ListNode cur=head;
ListNode temp=null;
while(pre!=null){
temp=pre.next; //先用temp接收pre的后继结点
pre.next=cur; //翻转
cur=pre;
pre=temp; //pre和cur向后移动
}
head.next=null; //最开始的头结点变成了尾结点
return cur;
}
例题5两两交换链表中的节点
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
此题使用递归方式比较方便
public ListNode swapPairs(ListNode head) {
if(head==null) return null; //首先判空,如果为空直接返回null
if(head.next==null) return head; //如果仅有一个节点也无需交换
ListNode cur=head;
ListNode pre=head.next;
ListNode temp=pre.next;
pre.next=cur; //交换相邻两个节点
cur.next=swapPairs(temp); //递归处理后面的部分
return pre; //返回交换之后的头节点
}
练习:设计链表
707. 设计链表 - 力扣(LeetCode) (leetcode-cn.com)
此题涉及头插法、尾插法、在指定位置插入、查找节点、删除节点,较为全面适合练习链表操作