力扣题型--链表(两数相加|两两交换链表中的节点|重排链表)

上篇文章:力扣--分治(归并排序)算法题II:计算右侧小于当前元素的个数,翻转对(无痛通关困难题)

目录

1.两数相加

理解题意

算法原理

代码

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

理解题意

算法原理

代码

方式一:递归

方式二:循环

3.重排链表

理解题意

算法原理

代码


1.两数相加

https://leetcode.cn/problems/add-two-numbers/description/

理解题意

在没有前置0并且是非空链表的前提下,将每个数字逆序存储,再将两个链表中的数字逆序相加,返回正常值的逆序。

算法原理

模拟两数相加的过程即可。逆序有助于我们完成代码。

先设计一个头结点,再创建一个变量用于存储进位值,再依次将每个链表节点中的数字通过尾插的方式进行相加即可。

代码

复制代码
class Solution 
{
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) 
    {
        ListNode* cur1 = l1, *cur2 = l2;
        ListNode* newhead = new ListNode(0);
        ListNode* prev = newhead;
        int t = 0;

        while(cur1 || cur2 || t) // t不为0时,证明还有进位
        {
            if(cur1)
            {
                t += cur1->val;
                cur1 = cur1->next;
            }
            if(cur2)
            {
                t += cur2->val;
                cur2 = cur2->next;
            }
            prev->next = new ListNode(t % 10);
            prev = prev->next;
            t /= 10;
        }

        prev = newhead->next;
        delete newhead;

        return prev;
    }
};

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

https://leetcode.cn/problems/swap-nodes-in-pairs/

理解题意

在不改变节点内部的值的情况下,进行链表中的两两交换。

算法原理

先创建一个空的头结点,这样方便后续的记录与交换。

之后的代码如上图所示,将prev的next与next相连,cur的next与nnext相连,如此重复,并且注意截至条件为next为空。

代码

方式一:递归

复制代码
class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        if(head == nullptr || head->next == nullptr) return head;

        auto tmp = swapPairs(head->next->next);
        auto ret = head->next;
        head->next->next = head;
        head->next = tmp;

        return ret;
    }
};

方式二:循环

复制代码
class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        ListNode* newhead = new ListNode(0);
        newhead->next = head;
        ListNode* prev = newhead;

        while(prev->next != nullptr && prev->next->next != nullptr)
        {
            ListNode* cur = prev->next;
            ListNode* next = cur->next;
            ListNode* nnext = next->next;

            prev->next = next;
            next->next = cur;
            cur->next = nnext;

            prev = cur;
        }

        prev = newhead->next;
        delete newhead;        
        return prev;
    }
};

3.重排链表

https://leetcode.cn/problems/reorder-list/description/

理解题意

进行实际的节点交换,给定单链表,将最后一个链表尾插在第一个链表之后,依次类推。

算法原理

使用快慢双指针找链表中点,再通过头插法进行对后半段链表逆序,最终合并两链表即可。

由于链表有奇偶数之分,根据画图分析,将slow->next往后的链表节点进行逆序更方便,见下图:

代码

复制代码
class Solution {
public:
    void reorderList(ListNode* head) {
        if(head == nullptr || head->next == nullptr || head->next->next == nullptr) return;

        // 快慢双指针找中间节点
        ListNode* slow = head, *fast = head;
        while(fast && fast->next)
        {
            slow = slow->next;
            fast = fast->next->next;
        }

        // 双指针将后半段指针逆序(头插法)
        ListNode* head2 = new ListNode(0);
        ListNode* cur = slow->next;
        slow->next = nullptr; // 断开链表
        while(cur)
        {
            ListNode* next = cur->next;
            cur->next = head2->next;
            head2->next = cur;
            cur = next;
        }

        // 双指针合并两段指针
        ListNode* ret = new ListNode(0);
        ListNode* prev = ret;
        ListNode* cur1 = head, *cur2 = head2->next;
        while(cur1)
        {
            // 先放第一个链表
            prev->next = cur1;
            cur1 = cur1->next;
            prev = prev->next;

            // 再放第二个链表
            if(cur2)
            {
                prev->next = cur2;
                cur2 = cur2->next;
                prev = prev->next;
            }
        }
        delete head2;
        delete ret;
    }
};

本章完。

相关推荐
MC皮蛋侠客5 小时前
Google Test 单元测试指南
c++·单元测试·google test
艾莉丝努力练剑6 小时前
【Linux:文件】Ext系列文件系统进阶
linux·运维·服务器·c++·文件系统·文件io·ext
kkeeper~6 小时前
0基础C语言积跬步之数据在内存中的存储
c语言·数据结构·算法
2401_868534787 小时前
论企业网络设计
数据结构
wabs6668 小时前
关于贪心算法的一些自我总结【力扣45.跳跃游戏II】【灵感来源:代码随想录】
算法·贪心算法·复盘
2401_876964138 小时前
【湖北专升本】2026湖北专升本真题PDF+备考资料汇总
数据结构·人工智能·经验分享·深度学习·算法·计算机视觉
basketball6168 小时前
C++ NULL 和 nullptr 区别 以及 nullptr 的核心实现
java·开发语言·c++
嗝o゚8 小时前
CANN GE 算子融合——融合算法与调度策略
算法·昇腾·cann·ge
小江的记录本9 小时前
【JVM虚拟机】垃圾回收GC:垃圾回收算法:标记-清除、标记-复制、标记-整理、分代收集(附《思维导图》+《面试高频考点清单》)
java·jvm·后端·python·算法·安全·面试
Fre丸子_9 小时前
自定义文件夹选取功能
c++