Loading

Leetcode24. 两两交换链表中的节点

题目描述

给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。

示例

image

提交的代码

class Solution {

    ListNode nextNode;

    public ListNode swapPairs(ListNode head) {
        //特殊化处理空链表
        if(head==null)return head;
        return recursiveSwap(head,head.next);
    }

    public ListNode recursiveSwap(ListNode pre,ListNode cur){
        //处理奇数链表最后一个的情况
        if(cur==null){
            return pre;
        }

        nextNode=cur.next;

        cur.next=pre;
        pre.next=nextNode;

        //处理偶数链表最后两个的情况
        if(nextNode==null)return cur;
        pre.next=recursiveSwap(nextNode,nextNode.next);
        return cur;
    }
}

个人使用的是递归的方式来实现的,思想就是当前递归层中的两个节点,后一个节点指向前一个节点,而前一个节点暂时指向后一个节点原来的后驱(这个后驱需要用额外的变量记录)。
这里的暂时指的是:如果下个递归层还能够处理的话,下个递归层返回的节点供给前一个节点的next来指向。这里返回的节点是有情况的,如果下个递归层还够两个节点的话,那么返回的节点就是交换过的节点中的cur,如果下个递归层不够两个:1.最后一个了,那么就直接返回pre 2.上一层处理的就是最后的两个,下个递归层是没有节点了的,那么这个时候之前的暂时就起到作用了,pre指向为null,并且当前递归层返回的是cur。

学习到的方法

image
这里需要使用虚头来完成代码的编写,统一插入操作。当然,不用虚头也可以,麻烦点。
需要使用到指针来指向需要交换的两个节点中的第一个节点的前驱,并且还要使用额外的空间来记录第一个节点和第三个节点的内存地址(因为要交换,可以大脑构思一下),接下来的操作就是如下。

class Solution {
    ListNode first;
    ListNode third;
    
    public ListNode swapPairs(ListNode head) {
        //先行处理空节点
        if(head==null)return null;
        //使用虚头来处理,因为涉及到插入,统一插入操作。当然,不使用虚头也能做
        ListNode fakeHead=new ListNode(-1,head);
        ListNode cur=fakeHead;
        while(cur.next!=null&&cur.next.next!=null){
            first=cur.next;
            third=cur.next.next.next;

            //开始交换
            cur.next=cur.next.next;
            cur.next.next=first;
            first.next=third;

            //cur跟进到要交换的两个节点中第一个节点的前驱
            cur=cur.next.next; 
        }
        return fakeHead.next;
    }
}
posted @ 2023-10-17 22:34  白布鸽  阅读(18)  评论(0)    收藏  举报