[Leetcode 25] Reverse Nodes in k-Group

题目

这里写图片描述

分析

1. 方法一:题目中提到可以采用常数量个空间,所以想到了,采用一个大小为k的数组空间来存储group值,然后利用遍历k步前记录的链表起始地址,来修改这个k-Group链表的值。(修改的是链表中存储的值,而非链表指针)
2. 方法二:先遍历k步,记录k-Group链表的起始地址,和终止地址,然后调用一个链表翻转的子函数,对这个记录下起始地址和终止地址的链表翻转操作。(需要遍历两遍链表)

方法一

C代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* reverseKGroup(struct ListNode* head, int k) {
    //传参有效性判断
    if(head==NULL || k<=0){
        return head;
    }
    //申请一个k大小的数组
    int value[k];

    struct ListNode* p = head;
    struct ListNode* pGroup = head;
    int i = 0;
    while(p != NULL){
        value[i] = p->val;
        if(i == (k - 1)){
            int j = 0;
            while(j < k){
                pGroup->val = value[k-1-j];
                   j++;
                pGroup = pGroup->next;
            }
            pGroup = p->next;
        }
        i = (i + 1) % k;
        p = p->next;
    }
    return head;
}
C++代码

编程注意事项 链表操作时候,一定要先确定需要修改的是哪几个指针,在指针修改时候,确保不会因为修改了当前的指针,断了与后面链表的连接。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        if(head==NULL || k <= 0){  //传参有效性判断
            return head;
        }

       int* value = new int[k];

        ListNode* p = head;
        ListNode* pGroup = head;
        int i = 0;
        while(p != NULL){
            value[i] = p->val;
            if(i == (k-1)){  //已经遍历k个数
                int j = 0;
                while(j < k){
                    pGroup->val = value[k-1-j];
                    j++;
                    pGroup = pGroup->next;
                }
                pGroup = p->next;
            }
            i = (i + 1) % k;
            p = p->next;
        }
        delete [] value;
        return head;
    }
};

方法二

C代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* reverseKGroup(struct ListNode* head, int k) {
    //传参有效性判断
    if(head==NULL || k<=1){
        return head;
    }

    struct ListNode* pStart = head;   //最终连接完的总链表
    struct ListNode* pEnd = NULL;

    struct ListNode* pStartK = head;
    struct ListNode* pEndK = NULL;
    struct ListNode* pNextK = head;

    int i = 0;
    while(head != NULL){
        if(i==(k-1)){       //找到k个节点,需要翻转
            pEndK = head;
            pNextK = head->next;   //保存需要翻转的k个节点后面链表地址

            struct ListNode* tmp = NULL;
            struct ListNode* current = pStartK;
            while(current != pNextK){
                tmp = current->next;
                current->next = pEndK;
                pEndK = current;
                current = tmp;
            }

            if( pEnd==NULL){     //将翻转完的子链表链接到已经翻转完的整体链表上
                pStart = pEndK;
                pEnd = pStartK;
            }else{
                pEnd->next = pEndK;
                pEnd = pStartK;
            }

            pEnd->next = pNextK;  //将未翻转的链表链接到已经翻转的后面

            pStartK = pNextK;
            i = (i + 1) % k;
            head = pNextK;

        }else{  
            i = (i + 1) % k; 
            head = head->next;
        }
    }
    return pStart;
}
C++代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        if(head==NULL || k <= 0){  //传参有效性判断
            return head;
        }

        ListNode* pStart = head;    //总体链表的头尾指针
        ListNode* pEnd = NULL;

        ListNode* pkStart = head;   //处理中的kGroup链表头尾指针
        ListNode* pkEnd = NULL;
        ListNode* pkNext = head;    //待处理的链表头指针 

        int i = 0;

        while(head != NULL){
            if(i == (k-1)){
                pkEnd = head;
                pkNext = head->next;    //后面还没有处理的链表起点地址

                ListNode* current = pkStart;    //翻转从pkStart到pkEnd之间的链表
                ListNode* tmp = NULL;           //翻转完,pkEnd变成是子链表的头结点,pkStart变成是子链表的末尾节点
                while(current != pkNext){
                    tmp = current->next;
                    current->next = pkEnd;
                    pkEnd = current;
                    current = tmp;
                }

                if(pEnd == NULL){       //将刚翻转完的子链表链接到总体链表上面
                    pStart = pkEnd;
                    pEnd = pkStart;
                }else{
                    pEnd->next = pkEnd;
                    pEnd = pkStart;
                }

                pEnd->next = pkNext;    //后面还没有处理的链表链接到已经处理完的链表末尾

                pkStart = pkNext;  
                i = (i+1)%k;
                head = pkNext;
            }else{
                i = (i+1)%k;
                head = head->next;
            }
        }
        return pStart;

    }
};
主要内容:本文详细介绍了一种QRBiLSTM(分位数回归双向长短期记忆网络)的时间序列区间预测方法。首先介绍了项目背景以及模型的优势,比如能够有效利用双向的信息,并对未来的趋势上限和下限做出估计。接着从数据生成出发讲述了具体的代码操作过程:数据预处理,搭建模型,进行训练,并最终可视化预测结果与计算分位数回归的边界线。提供的示例代码可以完全运行并且包含了数据生成环节,便于新手快速上手,深入学习。此外还指出了模型未来发展的方向,例如加入额外的输入特性和改善超参数配置等途径提高模型的表现。文中强调了时间序列的标准化和平稳检验,在样本划分阶段需要按时间序列顺序进行划分,并在训练阶段采取合适的手段预防过度拟合发生。 适合人群:对于希望学习和应用双向长短时记忆网络解决时序数据预测的初学者和具有一定基础的研究人员。尤其适用于有金融数据分析需求、需要做多一步或多步预测任务的从业者。 使用场景及目标:应用于金融市场波动预报、天气状况变化预测或是物流管理等多个领域内的决策支持。主要目的在于不仅能够提供精确的数值预计还能描绘出相应的区间概率图以增强结论置信程度。 补充说明:本教程通过一个由正弦信号加白噪构造而成的简单实例来指导大家理解和执行QRBiLSTM流程的所有关键步骤,这既方便于初学者跟踪学习,又有利于专业人士作为现有系统的补充参考工具。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值