优选算法——链表

1. 链表常用技巧和操作总结

2. 两数相加

题目链接2. 两数相加 - 力扣(LeetCode)

题目展示

题目分析:本题给的是逆序,其实降低了难度,逆序刚好我们从第一位开始加,算法原理其实就是模拟相加的过程。

代码实现

复制代码
/**
 * 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* addTwoNumbers(ListNode* l1, ListNode* l2) 
    {
        ListNode* cur1=l1,*cur2=l2;
        ListNode* newnode=new ListNode(0);//创建虚拟头节点
        ListNode* prev=newnode;
        int t=0;//记录进位
        while(cur1||cur2||t)
        {
            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=newnode->next;
        delete newnode;
        return prev;
    }
};

3. 两两交换链表中的结点

题目链接24. 两两交换链表中的节点 - 力扣(LeetCode)

题目展示

题目分析:本题我们就需要用到前面提到的技巧来解决,即创建虚拟头节点。

我们创建完虚拟头节点后,访问节点就会很方便;还有一点,就是我们不要吝啬空间,大胆地去定义变量。正如此题,我们想实现交换操作,涉及4个节点之间的变换,如果我们不定义变量去标记,那么指针的变换将会很复杂,容错率就会大大降低。

代码实现

复制代码
/**
 * 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) 
    {
        //处理特殊情况
        if(head==nullptr||head->next==nullptr)
        {
            return head;
        }
        //创建虚拟头节点
        ListNode* newHead=new ListNode(0);
        newHead->next=head;
        //定义变量来标记
        ListNode* prev=newHead,*cur=prev->next,*next=cur->next,*nnext=next->next;
        while(cur&&next)
        {
            //交换节点
            prev->next=next;
            next->next=cur;
            cur->next=nnext;
            //修改指针(顺序不能改)
            prev=cur;
            cur=nnext;
            if(cur)
            {
                next=cur->next;
            }
            if(next)
            {
                nnext=next->next;
            }
        }
        cur=newHead->next;
        delete newHead;
        return cur;
    }
};

大家能够看到,根据上面的图加上我们定义的变量,代码的逻辑是很清晰的,大家需要注意一些特殊情况的处理,以免造成程序崩了。

4. 重排链表

题目链接143. 重排链表 - 力扣(LeetCode)

题目展示

题目分析:本题大家一定要画图分析,找到其中的规律,其实本题是我们之前学过的三道题的综合。

代码实现

在实现之前,我们先来明确一个问题,大家来看下图:

大家可以看到,进行逆序操作时,有两种做法,这两种方法其实殊途同归,都可以实现逆序的操作,这里我更推荐大家用第一种,即让slow后面的节点进行逆序。

复制代码
​
/**
 * 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:
    void reorderList(ListNode* head) 
    {
        //处理边界情况
        if(head==nullptr||head->next==nullptr||head->next->next==nullptr)
        {
            return;
        }
        //1. 找到链表的中间节点
        ListNode* fast=head;
        ListNode* slow=head;
        while(fast&&fast->next)
        {
            slow=slow->next;
            fast=fast->next->next;
        }
        //2. 将slow后面的部分进行逆序操作------头插法
        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;
        }
        //3.合并两个链表
        ListNode* ret=new ListNode(0);
        ListNode* prev=ret;
        ListNode* cur1=head,*cur2=head2->next;
        while(cur1)
        {
            //先放第一个链表------尾插
            prev->next=cur1;
            prev=prev->next;
            cur1=cur1->next;
            //再放第二个链表
            if(cur2)
            {
                prev->next=cur2;
                prev=prev->next;
                cur2=cur2->next;
            }
        }
    }
};

​

这里大家注意代码的逻辑,对应题目分析中的图,找中间节点------快慢指针,逆序操作------头插法,合并链表------双指针。

5. 总结

本篇博客为大家介绍了几个链表的题目,之前在学习链表的时候也总结了一些题,具体大家有兴趣可以去看这两篇:单链表的应用-CSDN博客链表OJ题-CSDN博客。最后希望以上内容可以为大家带来帮助,感谢阅读!

相关推荐
大江东去浪淘尽千古风流人物1 分钟前
【SLAM新范式】几何主导=》几何+学习+语义+高效表示的融合
深度学习·算法·slam
铉铉这波能秀9 分钟前
LeetCode Hot100数据结构背景知识之列表(List)Python2026新版
数据结构·leetcode·list
重生之我是Java开发战士15 分钟前
【优选算法】模拟算法:替换所有的问号,提莫攻击,N字形变换,外观数列,数青蛙
算法
仟濹21 分钟前
算法打卡 day1 (2026-02-06 周四) | 算法: DFS | 1_卡码网98 可达路径 | 2_力扣797_所有可能的路径
算法·leetcode·深度优先
yang)21 分钟前
欠采样时的相位倒置问题
算法
历程里程碑25 分钟前
Linux20 : IO
linux·c语言·开发语言·数据结构·c++·算法
A尘埃27 分钟前
物流公司配送路径动态优化(Q-Learning算法)
算法
天若有情67328 分钟前
【自研实战】轻量级ASCII字符串加密算法:从设计到落地(防查岗神器版)
网络·c++·算法·安全·数据安全·加密
DeeplyMind38 分钟前
第七章:数据结构大比拼
数据结构·计算机科学·少儿编程·少儿科技读物
元亓亓亓39 分钟前
考研408--数据结构--day8--遍历序列&线索二叉树
数据结构·考研·408·线索二叉树