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

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

时间:2024-09-22 21:49:26浏览次数:12  
标签:奇偶 head ListNode 线性表 nullptr next 链表 节点

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,即交换后的链表的头节点。

标签:奇偶,head,ListNode,线性表,nullptr,next,链表,节点
From: https://blog.csdn.net/u014114223/article/details/142372447

相关文章

  • 数据结构之线性表——LeetCode:80. 删除有序数组中的重复项 II,88. 合并两个有序数组,4.
    80.删除有序数组中的重复项II题目描述80.删除有序数组中的重复项II给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用O(1)额外......
  • 数据结构之线性表——LeetCode:82. 删除排序链表中的重复元素 II,21. 合并两个有序链
    82.删除排序链表中的重复元素II题目描述82.删除排序链表中的重复元素II给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。运行代码classSolution{public:ListNode*deleteDuplicates(ListNode......
  • 双链表和循环链表
    线性表的链式和线性存储见前两篇文章一、双链表1.定义:在线性表的链式存储结构中,每个物理结点增加一个指向后继结点的指针域和一个指向前驱结点的指针域2.优点:(1)从任一结点出发可以快速找到其前驱结点和后继结点(2)从任一结点出发可以访问其他结点注意:双链表的密度比单链表......
  • 移除链表元素
    移除链表元素思路:1.首先判断链表是否为空,若为空直接返回head(null)2.若链表不为空,让prev记住要删除节点的前一个位置,cur指向要删除的元素位置,若cur指向的val==要删除的值,就让prev.next指向cur.next3.因为cur是从head的下一个节点位置开始判断的,就没有判断头节点是否为要......
  • 链表的中间结点
    链表的中间结点思路1:1.若链表为空,直接返回null2.若链表不为空,我们可以先求的链表的长度,让得到的链表长度/2,再让ListNodecur=head,cur走上链表长度/2次,就可以返回中间节点了publicintsize(ListNodehead){if(head==null){return0;......
  • 双链表定义与操作
    双链表的定义 与单链表不同的地方在于指针,双链表的指针多了个前向指针。点击查看代码typedefstructDNode{ ElemTypedata; DNode*prior,*next;}*DLinkList,DNode;双链表的初始化(initial) 双链表的创建也可分为带头节点和不带头节点(这里只放了不带头的初始化)。......
  • 链表(3)链表的基本操作
            单链表的基本操作主要有;①创建链表;②输出链表;③査我结点;④插入结点,⑤鹏除结点;⑥重组链表。下面分别进行介绍。一.创建链表        创建链表是指在程序运行时,进行动态内存分配,创建若千个结点,并把这些结点连接成串,形成一个链表。在进行动态......
  • 【数据结构】链表及其代码实现
    之前我们已经学习了顺序表,现在让我们来进行对链表的学习!!!【顺序表详解】......
  • 19080 反转链表
    ###思路1.初始化三个指针:`prev`(前驱节点),`curr`(当前节点),`next`(后继节点)。2.遍历链表,将当前节点的`next`指针指向前驱节点,实现反转。3.移动三个指针,继续反转下一个节点,直到遍历完整个链表。4.最后,将头节点指向新的头节点(即原链表的最后一个节点)。###伪代码```funct......
  • 单链表定义和操作
    首先是单链表的定义,使用结构体定义两个部分,分别是数据域和指针域。点击查看代码typedefstructLNode{ ElemTypedata; structLNode*next;}LNode,*LinkList;这里可以使用typedef关键字将后续的定义简化。具体例子如下:如果这样定义structLNode{}的话。在定义LNode类......