• 【leetcode】25. Reverse Nodes in k-Group


    题目说明

    https://leetcode-cn.com/problems/reverse-nodes-in-k-group/description/
    给出一个链表,每 k 个节点一组进行翻转,并返回翻转后的链表。
    k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么将最后剩余节点保持原有顺序。

    解法1


    首先遍历链表,记录结点个数,当满足个数等于k时,开始进行反转,反转完成后,个数重新计数。
    假设n为k区间中需要反转的第一个结点,n+k为最后一个结点。使用pre指向[n,n+k]区间的前一个结点(即n-1),使用cur进行遍历,满足条件时,cur指向n+k这个结点
    反转方法:对[n,n+k]进行遍历,每次将后一个结点指向前一个结点。[n,n+k]这个区间进行反转操作后,还需要使[n,n+k]这个区间的结点能够与两边串联起来:将pre指向n+k这个结点,并且n这个结点需要指向n+k+1这个结点。

    /*
     * 时间复杂度:O(n)
     */
    ListNode* reverseKGroup(ListNode* head, int k) {
        ListNode *dummy = new ListNode(0);
        dummy->next = head;
        ListNode *pre = dummy;
        ListNode *pre_in = NULL; //[n,n+k]区间操作时的前结点
        ListNode *cur = NULL;    //遍历整个结点
        ListNode *cur_in = NULL; //[n,n+k]区间操作时的当前结点
        ListNode *next = NULL;   //[n,n+k]区间操作时的下一结点
        ListNode *first = NULL;  //记录n这个结点
        int count = 0;
    
        cur = pre->next;
        while(cur){
            count ++;
            if (count == k){
                pre_in = pre;
                cur_in = pre->next;
                first = cur_in;
                for (int i = 0; i < k; i ++){//反转操作
                    next = cur_in->next;
                    cur_in->next = pre_in;
                    pre_in = cur_in;
                    cur_in = next;
                }
                pre->next = pre_in;  //pre指向n+k这个结点
                first->next = next;  //n这个结点需要指向n+k+1这个结点
                pre = first;         //移动pre结点到n结点,是为下一个k长度区间的前一个结点
                cur = pre->next;
                count = 0;           //重新计数
                continue;
            }
            cur = cur->next;
        }
        return dummy->next;
    }
    

    解法2


    两次遍历,第一次得到链表长度。
    第二次遍历每次进行k区间的反转。
    反转的方法:
    假设[n,n+k]这个区间进行反转,对第i(n<=i<=n+k)个结点进行反转时将n+i指向i-1,n-1指向i,n指向i+1,而其他点不需要变动

    /*
     * 时间复杂度:O(n)
     */
    ListNode* reverseKGroup(ListNode* head, int k) {
        ListNode *dummy = new ListNode(0);
        dummy->next = head;
        ListNode *pre = dummy;
        ListNode *cur = pre->next;
        ListNode *next = NULL;
        int num = 0;
    
        while(cur){
            cur = cur->next;
            num ++;
        }
        while(num >= k){
            cur = pre->next;
            next = cur->next;
            for (int i = 1; i < k; i ++){
                cur->next = next->next;
                next->next = pre->next;
                pre->next = next;
                next = cur->next;
            }
            num -= k;
            pre = cur;
        }
        return dummy->next;
    }
  • 相关阅读:
    关于多个EditText的OnTextChange事件陷入死循环的处理
    #define #include #undef的其中一个用法(目的)
    串行移位锁存并行输出可级联器件74HC595
    STM32F10xx CAN BUS相关库文件"stm32f10x_can.c"内的库函数解析
    STM32 之 NVIC(中断向量、优先级) 简述
    STM32F103xx bxCAN(Basic Extended CAN) 滤波机制
    VS上利用C#实现一个简单的串口程序记录
    如何去各型MCU的官网上下载正确的数据手册
    Cotex-M3内核STM32F10XX系列时钟及其配置方法
    Stm32 debug停留在"BKPT 0xAB"或者"SWI 0xAB"的解决办法。
  • 原文地址:https://www.cnblogs.com/JesseTsou/p/9582164.html
Copyright © 2020-2023  润新知