C++:Leetcode-链表-24两两交换链表中的节点

本文详细解析了如何使用C++解决LeetCode上的链表问题——两两交换链表中的节点。通过创建虚拟头节点、记录相邻节点以及交换指针来实现节点交换。文章提供了清晰的思路分析、代码实现以及运行流程图,有助于加深对链表操作的理解。
摘要由CSDN通过智能技术生成

C++:Leetcode-链表-24两两交换链表中的节点

链表联系题,加强虚拟头节点运用,加强节点交换后指针指向也随之改变的理解



题目

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


一、思路分析

结合画图进行理解
1、创建虚拟头节点、现节点方便后续操作
2、记录第1个节点和第3个节点,方便后续交换的操作
3、进行交换,步骤一:现节点即虚拟头节点指向2节点,此时cur->next为2节点
4、步骤二:2节点指向原来的1节点,原来1节点由temp1记录,此时cur->next->next为1节点
5、步骤三:1节点指向原来的3节点,原来3节点由temp2记录,此时cur->next->next->next为1节点的指向即3节点
6、两两交换完毕,现节点向后移动两位,完成一轮交换
7、不断循环,用while判定,当两个相邻节点都不为空时进行交换

重点理解:
1、节点进行交换后,节点的指向也随之改变,别漏了这个。
2、还有返回的是交换后的头节点,但mylist中的虚拟头结点指向没有改变,还是指向最初的1,而不是交换后的2(这个不影响leetcode通过,只是影响自己输出打印)

思路流程图如下:
步骤图

二、代码

/*
Leetcode-24两两交换链表中的节点

思路:
结合画图进行理解
1、创建虚拟头节点、现节点方便后续操作
2、记录第1个节点和第3个节点,方便后续交换的操作
3、进行交换,步骤一:现节点即虚拟头节点指向2节点,此时cur->next为2节点
4、步骤二:2节点指向原来的1节点,原来1节点由temp1记录,此时cur->next->next为1节点
5、步骤三:1节点指向原来的3节点,原来3节点由temp2记录,此时cur->next->next->next为1节点的指向即3节点
6、两两交换完毕,现节点向后移动两位,完成一轮交换
7、不断循环,用while判定,当两个相邻节点都不为空时进行交换
*/

#include "iostream"
#include "vector"
#include "list"

using namespace std;

//创建节点
class ListNode
{
public:
    int val;
    ListNode *next;
    ListNode() : val(0), next(nullptr) {}
    ListNode(int x) : val(x), next(nullptr) {}
    ListNode(int x, ListNode *l_next) : val(x), next(l_next) {}
};

//创建链表
class myLinkedList
{
public:
    int listsize;
    ListNode *dummyNode;

    myLinkedList()
    {
        listsize = 0;
        dummyNode = new ListNode(0);
    }

    ListNode *creatList(vector<int> &nums)
    {
        ListNode *current = new ListNode(nums[0]);
        dummyNode->next = current;
        for (int i = 1; i < nums.size(); i++)
        {
            current->next = new ListNode(nums[i]);
            current = current->next;
        }

        listsize += nums.size();
        return dummyNode->next;
    }

    void printList(ListNode *head)
    {
        ListNode *current = head;
        while (current != nullptr)
        {
            cout << current->val << "\t";
            current = current->next;
        }
        cout << endl;
    }
};

class Solution
{
public:
    ListNode *swapPairs(ListNode *head)
    {
        ListNode *dummyNode = new ListNode(0); //创建虚拟头节点,方便操作
        dummyNode->next = head;
        ListNode *cur = dummyNode;                                 //创建现节点,进行移动操作
        while (cur->next != nullptr && cur->next->next != nullptr) //当两个节点都不为空时,进行两两交换操作
        {
            ListNode *temp1 = cur->next;             //记录第一个节点,方便后续交换操作
            ListNode *temp2 = cur->next->next->next; //记录第三个节点,方便后续交换操作

            //开始进行交换
            //结合换图进行理解
            cur->next = cur->next->next;   //现节点即虚拟头节点指向2节点,此时cur->next为2节点,步骤1
            cur->next->next = temp1;       //2节点指向原来的1节点,原来1节点由temp1记录,此时cur->next->next为1节点,步骤2
            cur->next->next->next = temp2; //1节点指向原来的3节点,原来3节点由temp2记录,此时cur->next->next->next为1节点的指向即3节点,步骤3
            cur = cur->next->next;         //两两交换完毕,现节点向后移动两位,完成一轮交换
        }
        return dummyNode->next; //返回头节点,但mylist中的虚拟头结点指向没有改变,还是指向1,而不是交换后的2
    }
};

int main(int argc, const char **argv)
{
    myLinkedList mylist;
    vector<int> nums = {1, 2, 3, 4, 5};
    mylist.creatList(nums);
    mylist.printList(mylist.dummyNode->next);

    Solution s1;
    mylist.dummyNode->next = s1.swapPairs(mylist.dummyNode->next); //改变mylist中虚拟头节点的指向
    mylist.printList(mylist.dummyNode->next);

    return 0;
}

总结

链表的加强理解与加强运用。
参考代码随想录
https://www.programmercarl.com/0024.%E4%B8%A4%E4%B8%A4%E4%BA%A4%E6%8D%A2%E9%93%BE%E8%A1%A8%E4%B8%AD%E7%9A%84%E8%8A%82%E7%82%B9.html#%E6%80%9D%E8%B7%AF

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值