24.两两交换链表中的节点(Swap Nodes in Pairs)

题目描述

给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。

示例:

给定 1->2->3->4, 你应该返回 2->1->4->3.

说明:

  • 你的算法只能使用常数的额外空间。
  • 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

解题思路

       从链表首部开始,两两交换,利用递归;

public class Solution024 {

    private class ListNode {
        int val;
        ListNode next;

        ListNode(int x) {
            val = x;
        }
    }

    public ListNode swapPairs(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }

        ListNode p = head.next;
        head.next = swapPairs(p.next);
        p.next = head;
        return p;
    }
}
<think>我们正在处理用户关于C++链表节点交换实现的问题。用户明确要求查找“c++linkedlistswapnodesimplementation”。根据系统指令,我们需要:1.使用中文回答2.在行内数学达式时使用$...$,独立公式用$$...$$3.生成相关问题4.引用的段落末尾添加引用标识注意:用户的问题是关于链表交换两个节点的实现。在链表交换节点通常有两种情况:a)交换相邻的两个节点(如两两交换)b)交换任意两个节点(可能不相邻)根据用户的问题描述,他可能指的是相邻节点交换(因为提到了“swapnodesinpairs”),但问题中没有明确说明。因此,我们首先考虑实现相邻节点交换(如LeetCode24题),然后也可以提及任意节点交换的思路。另外,用户提供的引用[1]中正好有一个递归实现的示例(交换相邻节点),引用[2]则提到了删除节点,但我们可以借鉴指针修改的思想。因此,我们的回答结构:1.介绍链表节点交换的基本概念和挑战(因为链表是线性结构,交换节点需要修改指针)。2.给出相邻节点交换的递归实现(来自引用[1]的示例,但我们将用C++实现解释)。3.给出相邻节点交换的迭代实现(因为递归可能不适用于长链表,迭代更高效)。4.简要介绍任意两个节点交换的思路(需要处理更多边界情况,比如节点相邻节点是头节点等)。然后,根据指令生成相关问题。注意:我们引用的内容来自用户提供的引用[1]和[2],但实际回答中我们不需要直接复制,而是参考其思想,在适当位置标注引用。由于用户要求的是“implementation”,我们将提供代码示例解释。步骤:1.定义链表节点结构(通常是这样):structListNode{intval;ListNode*next;ListNode(intx):val(x),next(nullptr){}};2.实现相邻节点两两交换(递归法):递归终止条件:当前节点为空(没有节点交换)或当前节点的下一个节点为空(只剩一个节点,无法交换)。递归步骤:将当前节点和下一个节点交换,然后递归处理剩余的链表。3.实现相邻节点两两交换(迭代法):使用一个节点(dummynode)作为头节点的前驱,便于处理头节点交换。然后使用三个指针:pre(前一组交换后的最后一个节点),cur(当前第一个节点),next(当前第二个节点)。交换步骤:pre->next=next;cur->next=next->next;next->next=cur;然后更新pre和cur,继续下一组。4.任意节点交换:需要找到两个节点以及它们的前驱(因为要修改前驱的next指针)。注意特殊情况:两个节点相邻,其中一个节点是头节点,两个节点相同等。由于用户问题可能更关注相邻交换(因为引用[1]就是相邻交换),我们将重点放在相邻交换上。开始回答:</think>### C++链表节点交换实现详解 在C++中实现链表节点交换主要有两种场景:**相邻节点两两交换**和**任意节点交换**。核心思路是通过指针操作修改节点间的连接关系,注意处理边界条件(如头节点相邻节点、空链表等)。以下是具体实现: #### 1. 相邻节点两两交换(递归法) 适用于LeetCode 24题式需求,递归处理每对相邻节点: ```cpp struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(nullptr) {} }; ListNode* swapPairs(ListNode* head) { if (!head || !head->next) return head; // 终止条件:空或单节点 ListNode* newHead = head->next; // 新头节点为第二节点 ListNode* third = head->next->next; // 保存下一组起点 newHead->next = head; // 交换:2->1 head->next = swapPairs(third); // 递归处理剩余部分:1->递归结果 return newHead; // 返回新头节点 } ``` **时间复杂度**:$O(n)$,**空间复杂度**:$O(n)$(递归栈)[^1] #### 2. 相邻节点两两交换(迭代法) 避免递归栈开销,使用哑节点(dummy node)简化操作: ```cpp ListNode* swapPairs(ListNode* head) { ListNode dummy(0); dummy.next = head; ListNode* prev = &dummy; while (prev->next && prev->next->next) { ListNode* first = prev->next; ListNode* second = first->next; // 交换节点 prev->next = second; // prev->2 first->next = second->next; // 1->3 second->next = first; // 2->1 prev = first; // 移动prev到下一组前驱 } return dummy.next; } ``` **时间复杂度**:$O(n)$,**空间复杂度**:$O(1)$[^2] #### 3. 任意节点交换 交换链中任意两个节点(可能不相邻): ```cpp void swapNodes(ListNode** headRef, int x, int y) { if (x == y) return; // 相同节点无需交换 // 搜索节点及其前驱 ListNode *prevX = nullptr, *currX = *headRef; while (currX && currX->val != x) { prevX = currX; currX = currX->next; } ListNode *prevY = nullptr, *currY = *headRef; while (currY && currY->val != y) { prevY = currY; currY = currY->next; } if (!currX || !currY) return; // 未找到节点 // 更新前驱指针 if (prevX) prevX->next = currY; else *headRef = currY; // x是头节点 if (prevY) prevY->next = currX; else *headRef = currX; // y是头节点 // 交换后继指针 ListNode* temp = currY->next; currY->next = currX->next; currX->next = temp; } ``` **关键点**: - 处理相邻节点时直接修改`next`指针 - 节点相邻时需分别修改前驱的`next`和目标节点的`next` - 头节点特殊处理[^2] ### 常见问题分析 1. **空指针访问**:始终检查`next`是否为空 2. **头节点更新**:使用哑节点或二级指针 3. **相邻节点**:交换时避免形成环(如`node1->next = node2`后`node2->next`不可再指向`node1`)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值