【leetcode】24. 两两交换链表中的节点

前言

有些同学也许会被链表指针给搞的昏头转向,在纸上画出很久都没搞清楚。下面将介绍一种较为通用的方法:“新建链表法”,可以解决指针乱指等晕头转向的操作。只要掌握 删除节点和尾插法建表 ,大部分链表题目都可以转换为重新建表问题

“新建链表法”:即使用尾插法构建“新链表”,此处不是从新malloc链表节点,而是改变原节点的指针指向。其步骤如下:

  • 根据问题需求判断头节点是否会被改变,若有则在原链表上加上哨兵节点作为「虚拟头节点」。
  • 遍历原链表节点,把符合题意的节点“拆下来”,然后追加到“新链表”上。
  • “新链表”尾节点指针处理。(这很关键,因为保证“新链表”尾节点指针必须为NULL)

解题思路

下面以本题举例上述思想:本题意思是两个节点一组,后一个节点处理后要在前一个节点前面。

判断当前链表是否构成两个节点一组:

当前没有节点:遍历结束,所有节点已处理。

只有一个“拆下来”,追加到新链表后;
两个节点:先“拆”第二个节点并追加到新链表后;再“拆”第一个节点并追加到新链表后。
最后对“新建链表”尾节点的next指针进行置空操作。
没有让人昏头转向的指针转向操作,只涉及到如何「拆节点」和「往新链表后添加拆下的节点」。

作者:boille
链接:https://leetcode-cn.com/problems/swap-nodes-in-pairs/solution/tong-yong-lian-biao-si-lu-xin-jian-lian-p4nm8/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

​ /* 定义一个哑结点

​ 定义 end 指针表示链表最后一个元素, p 为交换的第一个元素, q 为交换的第二个元素, tmp 指向 p 的 下一次调换结点

​ 算法如下:

​ 首先将q 插入到 链表尾

​ 然后将p 加入到 链表尾

​ 更新end

​ 更新tmp, 根据tmp 更新 p, q (可能不足两组)*/

复杂度分析

空间复杂度 O(1)

时间复杂度 O(N)

代码

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        
       /* 定义一个哑结点
        定义 end 指针表示链表最后一个元素, p 为交换的第一个元素, q 为交换的第二个元素, tmp 指向 p 的 下一次调换结点

        算法如下:
        首先将q 插入到 链表尾
        然后将p 加入到 链表尾
        更新end
        更新tmp, 根据tmp 更新 p, q (可能不足两组)*/
        
        ListNode* dummy = new ListNode(0);
        ListNode* end = dummy;
        ListNode* tmp = head;
        if (tmp == nullptr) {
            return dummy->next;
        } else if (tmp->next == nullptr) {
            end->next = tmp;
            tmp->next = nullptr;
             return dummy->next;
        }

        ListNode* p = tmp;
        ListNode* q = tmp->next;

        while (1) {
            // 把 q p 加入到队列尾


            end->next = q;
            tmp = q->next;
            q->next = p;
            p->next = nullptr;
            //更新end
            end= end->next->next;
            end->next = nullptr;
            //更新tmp
           
            if (tmp == nullptr) {
                break;
            } else if (tmp->next == nullptr) {

                end->next = tmp;
                tmp->next = nullptr;
          

                break;
            }
            p = tmp;
            q = tmp->next;

        }
        return dummy->next;

    }

};

心得

  • 新建链表法可以学习掌握一下
  • 可以多找几个题目操作一下
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值