当前位置: 首页 > article >正文

数据结构之线性表——LeetCode:328. 奇偶链表,86. 分隔链表,24. 两两交换链表中的节点

328. 奇偶链表

题目描述

328. 奇偶链表

给定单链表的头节点 head ,将所有索引为奇数的节点和索引为偶数的节点分别组合在一起,然后返回重新排序的列表。

第一个节点的索引被认为是 奇数 , 第二个节点的索引为 偶数 ,以此类推。

请注意,偶数组和奇数组内部的相对顺序应该与输入时保持一致。

你必须在 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* oddEvenList(ListNode* head) {
        if (head == nullptr) {
            return head;
        }
        ListNode* evenHead = head->next;
        ListNode* odd = head;
        ListNode* even = evenHead;
        while (even != nullptr && even->next != nullptr) {
            odd->next = even->next;
            odd = odd->next;
            even->next = odd->next;
            even = even->next;
        }
        odd->next = evenHead;
        return head;
    }
};

代码思路

一、整体思路

这段代码的目的是将给定单链表按照节点索引的奇偶性进行分组重新排列。它通过遍历链表,将奇数索引的节点组成一个链表,偶数索引的节点组成另一个链表,最后将偶数链表连接到奇数链表的末尾。

二、函数分析

  1. 首先检查输入的链表头节点head是否为nullptr,如果是则直接返回head,表示空链表无需处理。
  2. 接着,定义一个指针evenHead指向链表的第二个节点,因为第二个节点的索引为偶数,这个指针将作为偶数链表的头节点。
  3. 然后定义两个指针oddeven,分别初始化为headevenHead,用于遍历奇数链表和偶数链表。
  4. 进入一个循环,循环条件是even不为nullptreven->next不为nullptr。在循环中:
    • even = even->next:将even指针移动到下一个偶数节点。
    • even->next = odd->next:将偶数节点even的下一个指针指向新的奇数节点的下一个节点,即连接下一个偶数节点。
    • odd = odd->next:将odd指针移动到下一个奇数节点。
    • odd->next = even->next:将奇数节点odd的下一个指针指向偶数节点even的下一个节点,即连接下一个奇数节点。
  5. 循环结束后,奇数链表和偶数链表都已处理完毕。
  6. 最后,将奇数链表的末尾节点odd的下一个指针指向偶数链表的头节点evenHead,完成链表的重新排列,并返回head,即重新排列后的链表的头节点。

86. 分隔链表

题目描述

86. 分隔链表

给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。

你应当 保留 两个分区中每个节点的初始相对位置。

运行代码

class Solution {
public:
    ListNode* partition(ListNode* head, int x) {
        ListNode *smallerDummy = new ListNode(0), *largerDummy = new ListNode(0);
        ListNode *smaller = smallerDummy, *larger = largerDummy;
        
        while (head != nullptr) {
            if (head->val < x) {
                smaller->next = head;
                smaller = smaller->next;
            } else {
                larger->next = head;
                larger = larger->next;
            }
            head = head->next;
        }
        
        smaller->next = largerDummy->next;
        larger->next = nullptr;
        
        return smallerDummy->next;
    }
};

代码思路

一、整体思路

这段代码的目的是将给定链表按照特定值x进行分隔,使得所有小于x的节点都出现在大于或等于x的节点之前,同时保持两个分区中每个节点的初始相对位置。

二、函数分析

  1. 首先创建两个新的链表头节点smallerDummylargerDummy,分别用于存储小于x的节点和大于或等于x的节点。同时创建两个指针smallerlarger,分别初始化为smallerDummylargerDummy,用于遍历和构建这两个新链表。
  2. 然后进入一个循环,遍历输入链表head。在循环中:
    • 无论当前节点连接到哪个链表,都要将head指针更新为head = head->next,以便继续遍历输入链表。
    • 如果当前节点的值大于或等于x,则将该节点连接到larger链表的末尾,即larger->next = head,然后更新larger指针为larger = larger->next
    • 如果当前节点的值小于x,则将该节点连接到smaller链表的末尾,即smaller->next = head,然后更新smaller指针为smaller = smaller->next
  3. 循环结束后,输入链表遍历完毕。此时,将smaller链表的末尾连接到larger链表的头部,即smaller->next = largerDummy->next。然后将larger链表的末尾设置为nullptr,以避免形成循环链表。
  4. 最后,返回smallerDummy->next,即分隔后的链表的头节点。

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

题目描述

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

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

运行代码

/**
 * 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=head->next;
        head->next=swapPairs(newhead->next);
       newhead->next=head;
       return newhead;

    }
};

代码思路

这段代码的目的是实现链表中相邻节点的两两交换。它采用递归的方式,从链表的头部开始,每次交换两个相邻节点,并继续递归处理剩余的链表部分。

  1. 首先检查输入链表的头节点head是否为nullptr,或者head->next是否为nullptr。如果是,说明链表中没有节点或者只有一个节点,无需进行交换操作,直接返回head
  2. 如果链表中有两个或以上的节点,定义一个新的头节点newheadhead->next,表示交换后的链表的新头节点。
  3. 接着,将head节点的下一个节点指向递归调用swapPairs(newhead->next)的结果,即处理完后面的链表部分后返回的新链表的头节点。这样可以将当前的两个节点与后面交换后的链表连接起来。
  4. 然后,将newhead节点的下一个节点指向head,完成当前两个节点的交换。
  5. 最后,返回newhead,即交换后的链表的头节点。

http://www.kler.cn/a/314416.html

相关文章:

  • Window下PHP安装最新sg11(php5.3-php8.3)
  • Qt_day4_Qt_UI设计
  • Jmeter性能测试 -3数据驱动实战
  • openSUSE 环境下通过 zypper 安装软件
  • 《MYSQL45讲》误删数据怎么办
  • vue中如何关闭eslint检测?
  • 基于React+JsonServer+Antddesign的读书笔记管理系统
  • 4.使用 VSCode 过程中的英语积累 - View 菜单(每一次重点积累 5 个单词)
  • 微软AI核电计划
  • SpringBoot 项目启动时指定外部配置文件
  • 【Android 13源码分析】WindowContainer窗口层级-4-Layer树
  • Android通知显示framework流程解析
  • Python中的魔法:栈与队列的奇妙之旅
  • 大语言模型的发展-OPENBMB
  • ICM20948 DMP代码详解(34)
  • 欧美游戏市场的差异
  • 漏洞复现_永恒之蓝
  • AI助力低代码平台:从智能化到高效交付的全新变革
  • 山体滑坡检测系统源码分享
  • STM32 通过 SPI 驱动 W25Q128
  • 【JS】垃圾回收机制与内存泄漏
  • mxnet 的显存分配机制
  • Gitlab学习(009 gitlab冲突提交)
  • 小程序与APP的区别
  • 大数据-137 - ClickHouse 集群 表引擎详解2 - MergeTree 存储结构 一级索引 跳数索引
  • 面试八股--MySQL命名规范