算法——两两交换链表中的节点(leetcode24)
这是一道对于链表节点进行操作的题目非常考验对于链表操作的基本功;
解法:
本题的解法结合下图来进一步解释
创建一个虚拟节点指向头结点以便使代码逻辑看起来更为简便且操作节点容易,定义cur是为了方便找到cur之后的两个节点进行交换操作定义pre和aft是为了保存执行步骤二以及步骤三时需要用到的节点;如果我们想交换节点1和节点2的话那么就需要依次执行步骤一、步骤二、步骤三这时节点1和节点2便完成了交换的操作
接着我们移动cur(cur=cur.next.next)以此来交换之后的两个节点,对于此操作的终止条件来说如果是偶数个节点那么只需判断cur.next==null即可因为我们的cur指针是指向两个交换节点的前一个节点如果是奇数个节点那么我们只需让cur.next.next等于null终止循环即可得到节点两两交换的链表返回vNode.next即可;
反思:
我刚开始做这道题的时候只想着两两交换节点首先将节点数量为空节点数量为1个的情况过滤出去直接返回head然后就是让虚拟头结点指向节点2让节点2指向节点1,节点1指向节点3接着移动指向节点1和节点2的指针于节点3和节点4再让其交换即可然而这种交换的解法是完全不对的在解题过程中总是报空指针的问题即使不报空指针的问题也只能解出一部分测试用例偶数个节点的测试用例一直是不对的后又听了卡尔老师的讲解视频后才发现自己的节点操作完全就是错误的会造成输出时在节点3之后只输出奇数节点,偶数节点全部都指向自己的前一个节点也就是奇数节点(例节点4指向节点3节点6指向节点5)是没有节点指向偶数节点的如下图所示,对于这种操作还是自己对于链表操作的基本功不够熟练需加强操作和理解。
/**
* 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 swapPairs(ListNode head) {
ListNode vNode=new ListNode();
vNode.next=head;
ListNode cur=vNode;
ListNode pre;
ListNode aft;
while(cur.next!=null&&cur.next.next!=null){
pre=cur.next;
aft=cur.next.next.next;
cur.next=cur.next.next;
cur.next.next=pre;
cur.next.next.next=aft;
//移动cur
cur=cur.next.next;
}
return vNode.next;
}
}