206.反转链表24.两两交换链表的结点
206.反转链表
题目链接 反转链表
题目描述
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

思路
1.双指针法
- 定义一个前指针pre和一个遍历指针cur,前指针用来反转指针指向;
- 前指针初始指向null;
- 定义临时指针temp保存cur的后继,然后使cur.next指向cur的前驱pre,
- 前指针pre指向cur进行移动,遍历指针cur指向temp进行移动,
- 直到pre->tail,cur->null时,才停止循环;
- pre即反转后的链表的头结点,返回pre.
2.递归法
- 递归法和双指针法的逻辑思路相同
- 代码实现相近,但更为简洁
观察图片更易理解

代码
1.双指针法
点击查看代码
class Solution {
//双指针法
public ListNode reverseList(ListNode head) {
//定义遍历指针
ListNode cur = head;
//定义cur的前驱
ListNode pre =null;
//定义临时指针
ListNode temp;
while(cur!=null){//cur->null则pre->head
//cur的后继暂存于temp
temp = cur.next;
//指针反转:-->to<--
cur.next = pre;
//移动pre和cur指针
pre = cur;
cur = temp;
}
return pre;
}
}
2.递归法
点击查看代码
class Solution {
public ListNode reverseList(ListNode head) {
return reverse(head,null);
}
ListNode reverse(ListNode cur,ListNode pre){
if(cur==null) return pre;
ListNode temp = cur.next;
cur.next = pre;
return reverse(temp,cur);
}
}
总结
这道题需要熟练掌握双指针的写法,然后再去写递归的代码就非常简单了。
24.两两交换链表的结点
题目链接 两两交换链表的结点
题目描述
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。

思路
- 要操作后两个结点一定需要前面一个结点
- 设置虚拟结点,要不然每次针对头结点(没有前一个指针指向头结点),还要单独处理。
代码
点击查看代码
class Solution {
public ListNode swapPairs(ListNode head) {
//设置虚拟头结点
ListNode dummy = new ListNode(0,head);
//代表cur指向的结点之后的3个结点
ListNode pre,mid,last;
ListNode cur = dummy;
while(cur.next!=null && cur.next.next!=null){
pre = cur.next;
mid = pre.next;
last = mid.next;
//交换结点
cur.next = mid;
mid.next = pre;
pre.next = last;
//cur移动
cur = pre;//注意这里不是cur=mid,由于pre,mid已经进行了交换,故选择pre
}
//返回头结点
return dummy.next;
}
}
总结
- 练习过程中容易出现空指针异常,记得注意循环的条件,结点数为偶数,则
cur.next!=null;结点数为奇数,则cur.next.next!=null;且两个条件需要同时满足才能进入循环; - 涉及链表结点的增删改,建议设置虚拟头结点.
本文来自博客园,作者:像峰一样,转载请注明原文链接:https://www.cnblogs.com/peak-like/articles/17629469.html

刷题第5天:我与链表
浙公网安备 33010602011771号