LeetCode [24][25] k个一组反转链表

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

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

扩展题目

  • 24解法1:
cpp 复制代码
// 迭代法难搞
    ListNode* swapPairs(ListNode* head) {
        if(head == nullptr || head->next == nullptr) return head;
        ListNode* ret = head->next;//用于返回的节点
        ListNode* p1 = head;
        ListNode* p2 = p1->next;
        ListNode* p3 = p2->next;//首先记录三个节点
        ListNode* tail = new ListNode();//记录本次操作的尾结点
        while(p3) 
        {
            p2->next = p1;//p2指向p1
            p1->next = p3;//p1指向下一次要翻转的p3,保证链表不断
            tail->next = p2;//上次的尾节点指向本次的头
            if(p3->next == nullptr) break;//如果此时p3->next为空,说明到链表尾部了,结束
            tail = p1;//更新tail,p1, p2, p3
            p1 = tail->next;
            p2 = p1->next;
            p3 = p2->next;
        }
        tail->next = p2;//结束循环后,tail指向当前的p2
        p2->next = p1;//p2指向p1
        p1->next = p3;//p1指向p3

        return ret;
    }
  • 24解法2
cpp 复制代码
//递归np
ListNode* swapPairs(ListNode* head) {
        if(head == nullptr || head->next == nullptr)
            return head;
        ListNode* p1 = head;
        ListNode* p2 = head->next;
        
        p1->next = swapPairs(p2->next);
        p2->next = p1;
        return p2;
    }
  • 25解法1
cpp 复制代码
// 迭代解法
ListNode* reverse(ListNode* head)
    {
        if(head == nullptr || head->next == nullptr) return head;
        ListNode* node1 = head;
        ListNode* node2 = node1->next;
        while(node1 && node2 && node2->next) 
        {
            node1 = node2;
            node2 = node2->next;
        }
        node1->next = nullptr;//node1为倒数第二个节点,node2为尾结点
        node2->next = reverse(head);//断开node1,node2指向翻转号的剩余head
        return node2;
    }
    ListNode* reverseKGroup(ListNode* head, int k) {
        if(head == nullptr || head->next == nullptr) return head;
        
        ListNode* tail = head;//记录当前中移动节点,可以放在while中
        ListNode* nextHead = head;//记录下一次翻转的头节点
        ListNode* res = nullptr;//用于返回
        ListNode* lastTail = nullptr;//记录上一次翻转的尾结点
        
        while(nextHead)
        {
            ListNode* curHead = nextHead;//此次的头结点
            tail = nextHead;//滑动节点
            int i = k;//单独一个变量记录i
            while(--i && tail) tail = tail->next;//找到本次翻转的尾结点,或者链表尾
            if(tail == nullptr)//如果已经到链表尾结点,不用再翻转
            {
                lastTail->next = nextHead;//上次的尾结点指向当前的尾,然后结束
                break;
            }
            nextHead = tail->next;//首先更新下一个Head
            tail->next = nullptr;//当前tail断开
            ListNode* ret = reverse(curHead);//把本次处理的链表翻转
            if(res == nullptr) res = ret;//用于返回res等于第一次翻转的链表
            if(lastTail)//使用每一个node的时,都要显式的判断一下是否为空
                lastTail->next = ret;//上次的tail指向本次翻转链表的头
            ListNode* curTail = ret;//求取本次翻转链表之后的tail
            while(curTail && curTail->next) curTail = curTail->next;
            lastTail = curTail;//更新此次tail
        }
        return res;
    }
  • 25解法2
cpp 复制代码
ListNode* reverse(ListNode* node1, ListNode* node2)
    {
        ListNode* pre = nullptr;
        ListNode* cur = node1;
        ListNode* next = nullptr;
        while(cur != node2)
        {
            next = cur->next;
            cur->next = pre;
            pre = cur;
            cur = next;
        }
        return pre;
    }
    ListNode* reverseKGroup(ListNode* head, int k) {
        if(head == nullptr || head ->next == nullptr) return head;
        ListNode* node1 = head;
        ListNode* node2 = head;          
        int i = k;
        while(i-- && node2) node2 = node2->next;//找到翻转链表的下一个结点
        if(node2 == nullptr && i >= 0)//如果到达链表尾部,直接返回
            return node1;
        ListNode* newHead = reverse(node1, node2);//翻转链表
        node1->next = reverseKGroup(node2, k);//递归进入下一轮
        return newHead;
    }
相关推荐
fancy1661661 小时前
力扣top100 矩阵置零
人工智能·算法·矩阵
小南家的青蛙1 小时前
LeetCode面试题 01.09 字符串轮转
java·leetcode
kedvellek1 小时前
Linux 内核链表宏的详细解释
linux·运维·链表
元亓亓亓1 小时前
LeetCode热题100--240.搜索二维矩阵--中等
算法·leetcode·矩阵
lybugproducer2 小时前
浅谈 Redis 数据类型
java·数据库·redis·后端·链表·缓存
明月看潮生2 小时前
青少年编程与数学 02-019 Rust 编程基础 09课题、流程控制
开发语言·算法·青少年编程·rust·编程与数学
oioihoii2 小时前
C++23 views::slide (P2442R1) 深入解析
linux·算法·c++23
yuhao__z3 小时前
代码随想录算法训练营第六十三天| 图论9—卡码网47. 参加科学大会,94. 城市间货物运输 I
算法·图论
June`3 小时前
专题三:穷举vs暴搜vs深搜vs回溯vs剪枝(全排列)决策树与递归实现详解
c++·算法·深度优先·剪枝
vlln3 小时前
适应性神经树:当深度学习遇上决策树的“生长法则”
人工智能·深度学习·算法·决策树·机器学习