leetcode 143 重排链表

目录

一、题目描述

二、解题思路

整体思路

具体思路

边界处理:

一、将链表对半分成两份

二、翻转后半部分链表

三、合并两个链表

三、代码实现

一、题目描述

二、解题思路

整体思路

题目要求把重排链表,本质上是一个模拟的问题,我们可以通过以下三步来解决这个问题:

(1)首先,将链表对半分成两份(双指针法);

(2)接着,将后面的链表进行逆转(原地逆转或者头插法);

(3)最后,将前半部分节点构成的链表和第二部分翻转后的链表进行合并(双指针);

具体思路

边界处理:

如果链表为空,或者链表只有一个节点、有两个结点,无需重排,直接return;

一、将链表对半分成两份

(1)定义快慢双指针slow,fast并初始化,当fast不为空且fast->next不为空时,slow走一步,fast走两步,以示例1(结点数为偶数)和示例2(结点数为奇数)为例,循环结束后指针的指向如下:

(2)定义指针first和second分别指向两个新链表的头节点,将两个链表断开,即slow->next=nullptr;

二、翻转后半部分链表

(1)初始化三个指针

<1>指针pre用指向翻转后的头节点,初始化为nullptr(因为开始时未进行翻转);

<2>指针current用于指向真正完成翻转操作的结点,初始化为second;

<3>指针next用于保存正在处理的结点的下一个位置,避免指针丢失;

(2)当current不为nullptr时进行循环

<1>首先,将next的值修改为current的next;

<2>接着,将current的next值修改为pre;

<3>然后,将pre的值修改为current;

<4>最后,将current后移,翻转下一个结点;

(3)翻转完成后,更新second的值为pre

三、合并两个链表

当first和second的值均不为nullptr时,进行循环:

<1>指针firstnext用于记录first的下一个位置的地址,指针secondnext用于记录second的下一个位置的地址;

<2>将second指向的结点接入first指向的结点的后面;

<3>更新first和second的值;

三、代码实现

cpp 复制代码
/**
 * 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&&!head->next&&!head->next->next) return ;

        //1.拆分两个链表(快慢双指针)
        ListNode* slow=head;
        ListNode* fast=head->next;
        while(fast&&fast->next){
            slow=slow->next;
            fast=fast->next->next;
        }
        ListNode* first=head;
        ListNode* second=slow->next;
        //断开两个链表
        slow->next=nullptr;

        //2.翻转second链表(原地翻转)
        ListNode* pre=nullptr;        //保存翻转后的头节点
        ListNode* current=second;     //保存正在处理的节点
        ListNode* next;               //保存下一个节点
        while(current){
            next=current->next;
            current->next=pre;
            pre=current;
            current=next;
        }
        second=pre;

        //3.合并两个链表
        while(first&&second){
            ListNode* firstnext=first->next;
            ListNode* secondnext=second->next;

            second->next=first->next;
            first->next=second;

            first=firstnext;
            second=secondnext;
        }
    }
};
相关推荐
NiceCloud喜云3 小时前
Opus 4.8 的 Effort Control 怎么选:Low 到 Max 五档策略
android·java·大数据·前端·c++·python·spring
小羊在睡觉3 小时前
力扣84. 柱状图中最大的矩形
后端·算法·leetcode·golang·go
cjhbachelor4 小时前
c++继承
c++
3DVisionary4 小时前
蓝光三维扫描:医疗制造的精度焦虑怎么解
人工智能·算法·制造·蓝光三维扫描·医疗制造·三维检测·义齿检测
好评笔记4 小时前
机器学习面试八股——常用损失函数
人工智能·深度学习·算法·机器学习·校招
weixin_468466854 小时前
全局与局部注意力机制新手实战指南
人工智能·python·深度学习·算法·自然语言处理·transformer·注意力机制
肩上风骋4 小时前
C++14特性
开发语言·c++·c++14特性
sheeta19984 小时前
LeetCode 每日一题笔记 日期:2026.05.29 题目:3300. 最小元素
笔记·leetcode
_日拱一卒4 小时前
LeetCode:994腐烂的橘子
java·数据结构·算法·leetcode·深度优先
珂朵莉MM5 小时前
第七届全球校园人工智能算法精英大赛-算法巅峰赛产业命题赛第3赛季优化题--束搜索
人工智能·算法