每日两题 / 24. 两两交换链表中的节点 && 25. K 个一组翻转链表(LeetCode热题100)

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

定义三个指针,交换前先保存ntnt指针为next->next,cur和next两个节点,然后将pre->next指向next

若pre为空,说明当前交换的节点为头两个节点,不需要修改pre->next

若cur不为空而next为空,则将pre->next指向cur

然后根据ntnt更新三个节点,当cur或者next为nullptr时,终止交换

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:
    ListNode* swapPairs(ListNode* head) {
        ListNode *pre = nullptr;
        ListNode *cur = head, *next = nullptr;
        if (cur) next = cur->next;
        if (next) head = next;
        while (next && cur)
        {
            ListNode *ntnt = next->next;
            next->next = cur; cur->next = nullptr;
            if (pre) pre->next = next;
            pre = cur, cur = ntnt;
            if (cur) next = cur->next;
        }
        if (pre && cur && (next == nullptr)) pre->next = cur;
        return head;
    }
};

25. K 个一组翻转链表 - 力扣(LeetCode)

先统计俩表中节点的数量n,需要翻转(n / k)组链表

使用哨兵new_head作为伪头节点

记录上一次k组的尾节点,初始为new_head

翻转完一组节点,将尾节点的next指向刚才翻转一组节点的头节点

对于每组节点的翻转,使用三个指针,将pre->cur修改cur->pre,再用next更新两个指针(pre = cur,cur = next)

每个子链表需要翻转k - 1次,一共需要翻转n / k组

最后,若k不能整除n,那么将上一组节点的尾节点next指向剩下节点的头节点

若k能整除n,那么将上一组节点的尾节点next指向nullptr

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:
    ListNode* reverseKGroup(ListNode* head, int k) {
        int n = 0;
        ListNode *cur = head;
        while (cur)
        {
            cur = cur->next;
            n ++ ;
        }
        ListNode *new_head = new ListNode;
        ListNode *pre = head;
        ListNode *hhead = nullptr, *tail = new_head;
        if (pre) cur = pre->next;
        for (int i = 0; i < n / k; ++ i)
        {            
            ListNode *new_tail = pre;
            for (int j = 0; j < k - 1; ++ j)
            {
                ListNode *next = cur->next;
                cur->next = pre;
                pre = cur, cur = next;
            }
            hhead = pre, tail->next = hhead, tail = new_tail;
            if (cur) pre = cur, cur = cur->next;
        }
        if (n % k) tail->next = pre;
        else tail->next = nullptr;
        return new_head->next;
    }
};
相关推荐
剑神一笑9 小时前
Linux pgrep 命令详解:按名称查找进程 PID 的高效方法
linux·运维·chrome
剑神一笑9 小时前
Linux killall 命令详解:按进程名批量终止进程的原理与实践
linux·运维·chrome
_日拱一卒13 小时前
LeetCode:207课程表
java·数据结构·算法·leetcode·职场和发展
日取其半万世不竭13 小时前
iftop、nethogs 和 nload:Linux 服务器网络流量实时监控工具介绍
linux·运维·服务器
mounter62514 小时前
Linux 内核资源管理:控制组(cgroup)的演进与“策略组”新提案
linux·运维·服务器·cgroup·kernel
bksczm14 小时前
文件在磁盘中的存储方式
linux·运维·服务器
L16247614 小时前
OpenSSH 半自动升级方案(独立编译 + 手动迁移 + 重建 systemd 服务)
linux·服务器·ssh
半旧夜夏14 小时前
【保姆级】微服务组件环境搭建(Docker Compose版)
java·linux·spring cloud·微服务·云原生·容器
爱莉希雅&&&15 小时前
zabbix快速搭建和使用
android·linux·数据库·zabbix·监控
z2005093015 小时前
【linux学习】深入理解linux文件I/O,从C标准库到内核态
linux·学习·操作系统