给定一个链表,一次颠倒链表k的节点并返回其修改列表。如果节点的数量不是k的倍数,那末最后的剩余节点应该保持原样。
来源:互联网 发布:修改软件下载 编辑:程序博客网 时间:2024/06/16 16:07
本题源自LeetCode
--------------------------------------------------------------------
思路:
利用栈结构的解法,时间复杂度O(n),空间复杂度O(k)
1:从左到右遍历链表,如果栈的大小不等于k,就将节点不断压入栈中
2:当栈的大小第一次达到k时,说明第一次凑齐了k个节点进行逆序,从栈中依次弹出
这些节点,并根据弹出顺序依次链接,这一组逆序完成后,需要记录一下新的头部,
同时第一组的最后一个节点(原来是头结点)应该链接下一个节点。
3:步骤2之后,当栈的大小每次达到k时,说明又凑齐了一组应该进行逆序的节点,从
栈中依次弹出这些节点,并根据弹出的顺序重新链接。这一组逆序完成后,该组的第一
个节点(原来是该组最后一个节点)应该被上一组的最后一个节点链接上,这一组的最
后一个节点(原来是该组第一个节点)应该链接下一个节点。然后继续去凑下一组,直
到链表被遍历完成。
代码:
void reverseCore(ListNode* start,ListNode* end,ListNode* &newStart,ListNode* &newEnd){ //用的指针的引用,也可以用 **指针的指针ListNode* pNext=NULL; ListNode* p=start; ListNode* pre=NULL; newStart=end; newEnd=start; ListNode* nextNode=end->next; while(p!=nextNode){ pNext=p->next; p->next=pre; pre=p; p=pNext; } } ListNode *reverseKGroup(ListNode *head, int k) { ListNode* p=head; ListNode* newHead=NULL; ListNode* start=head; ListNode* pre=NULL; ListNode* pNext=NULL; int count=1; while(p){ pNext=p->next; if(count==k){ //节点数量到K 个 反转部分链表 ListNode* newStart=NULL; ListNode* newEnd=NULL; reverseCore(start,p,newStart,newEnd); if(newHead==NULL) //新链表的头指针 newHead=newStart; if(pre) pre->next=newStart; //保持链表链接 newEnd->next=pNext; pre=newEnd; //保存上一个链表的尾节点 start=pNext; //保存每个局部链表的头 count=0; //count清零 } p=pNext; count++; } return newHead?newHead:head; }
思路2 :
考虑 用递归即 翻转pairs,翻转x~x+(k-1)之间的节点, x->next = reverseKGroup(x+k,k)
代码:
ListNode* reverseCore(ListNode* start,ListNode* end){ //用的指针的引用,也可以用 **指针的指针ListNode* pNext=NULL; ListNode* p=start; ListNode* pre=NULL; while(p!=end){ pNext=p->next; p->next=pre; pre=p; p=pNext; } return pre; } ListNode *reverseKGroup(ListNode *head, int k) { if(head==NULL||k<2) return head; ListNode *p=head; for(int i=0;i<k;i++){ if(!p) return head; p=p->next; } ListNode* newHead=reverseCore(head,p); //反转K链表 head->next=reverseKGroup(p,k); //保持链表不断。 return newHead; }
思路3 非递归
遍历链表,每遍历k个节点,就反转。并且保持链表不断开
ListNode *reverseKGroup(ListNode *head, int k) { if(head==NULL||k<2) return head; ListNode *p=head; int len=0; while(p){ p=p->next; len++; } ListNode* root=new ListNode(0); root->next=head; ListNode* pre=root; p=head; ListNode* pNext=NULL; for(int i=0;i<len/k;i++){ //循环len/k次 for(int j=1;j<k;j++){ //每次反转k 个节点 pNext=p->next; p->next=pNext->next; pNext->next=pre->next; pre->next=pNext; } pre=p; //保持链表不断开 p=p->next; } return root->next; }
阅读全文
0 0
- 给定一个链表,一次颠倒链表k的节点并返回其修改列表。如果节点的数量不是k的倍数,那末最后的剩余节点应该保持原样。
- 求链表的倒数第K个节点,如果K大于链表长度则返回NULL
- 找出二叉树中距离给定节点为k的节点
- 给定一个链表,交换每两个相邻节点并返回其头部。
- 随机返回一个链表的节点
- 给定一个链表,删除链表中倒数第n个节点,返回链表的头节点。
- C实现简单单向链表,一次遍历查找倒数第k个节点的值
- 查找单链表的倒数第k个节点,要求只能遍历一次链表
- 查找单链表的倒数第k个节点,要求只能遍历一次链表
- 链表--查找单链表的倒数第k个节点,要求只能遍历一次链表
- 查找单链表的倒数第k个节点,要求只能遍历一次链表
- 查找单链表的倒数第k个节点,要求只能遍历一次链表
- 输出链表的倒数第k个节点
- 寻找链表的倒数第k个节点
- 寻找单向链表的倒数第k个节点
- 链表的倒数第k个节点
- 输出链表的倒数第k个节点
- 寻找链表的倒数第K个节点
- 人脸检测——DDFD
- [Java读书笔记]之Swing
- [学习笔记] 树状数组区间加+区间求和
- 整数全排列问题
- 不同的路径
- 给定一个链表,一次颠倒链表k的节点并返回其修改列表。如果节点的数量不是k的倍数,那末最后的剩余节点应该保持原样。
- leetcode19Remove Nth Node From End of List
- Java 8 – 怎样对Map排序
- BP算法
- AD的多根走线
- C++笔记(第四章)
- Jam的计数法
- 数据结构--向量
- kindeditor用法简介