[Leetcode 25] Reverse Nodes in k-Group

来源:互联网 发布:c语言中字符串处理函数 编辑:程序博客网 时间:2024/06/08 20:14

题目

这里写图片描述

分析

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;    }};
0 0
原创粉丝点击