#include "000库函数.h"

 struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
/************************自己解答****************************/
//不含头结点,链表中的数据按照k个k个地翻转,使用栈进栈出原理
class Solution {
public:
ListNode* reverseKGroup(ListNode* head, int k) {
if (k <= || !head || !(head->next))return head;
ListNode* Res = new ListNode();
ListNode* r = Res;
ListNode* p = head;
stack<int> S;
while (p) {
S.push(p->val);
p = p->next;
if (S.size() == k) {
while (!S.empty()) { //采用尾插法
ListNode* q = new ListNode();
q->val = S.top();
r->next = q;
r = q;
S.pop();
}
}
}
if (S.size()) {
while (!S.empty()) { //采用头插法
ListNode* q = new ListNode();
q->val = S.top();
q->next = r->next;
r->next = q;
S.pop();
}
}
return Res->next; } }; /*******************************博客答案***************************/
//这道题让我们以每k个为一组来翻转链表,实际上是把原链表分成若干小段,
//然后分别对其进行翻转,那么肯定总共需要两个函数,一个是用来分段的,
//一个是用来翻转的,我们就以题目中给的例子来看,对于给定链表1->2->3->4->5,
//一般在处理链表问题时,我们大多时候都会在开头再加一个dummy node,因为翻转链表时头结点可能会变化
//为了记录当前最新的头结点的位置而引入的dummy node,那么我们加入dummy node后的链表变为
//- 1->1->2->3->4->5,如果k为3的话,我们的目标是将1, 2, 3翻转一下,那么我们需要一些指针
//,pre和next分别指向要翻转的链表的前后的位置,然后翻转后pre的位置更新到如下新的位置: //复制代码
//- 1->1->2->3->4->5
//| | |
//pre cur next
//
//- 1->3->2->1->4->5
//| | |
//cur pre next
//复制代码 //以此类推,只要cur走过k个节点,那么next就是cur->next,
//就可以调用翻转函数来进行局部翻转了,注意翻转之后新的cur和pre的位置都不同了,
//那么翻转之后,cur应该更新为pre->next,而如果不需要翻转的话,cur更新为cur->next, //解法一://耗时超过自己的解答 class Solution {
public:
ListNode* reverseKGroup(ListNode* head, int k) {
if (!head || k == ) return head;
ListNode *dummy = new ListNode(-), *pre = dummy, *cur = head;
dummy->next = head;//添加头结点
for (int i = ; cur; ++i) {
if (i % k == ) {
pre = reverseOneGroup(pre, cur->next);
cur = pre->next;
}
else {
cur = cur->next;
}
}
return dummy->next;
}
ListNode* reverseOneGroup(ListNode* pre, ListNode* next) {
ListNode *last = pre->next, *cur = last->next;
while (cur != next) {
last->next = cur->next;
cur->next = pre->next;
pre->next = cur;
cur = last->next;
}
return last;
}
}; //我们也可以在一个函数中完成,我们首先遍历整个链表,统计出链表的长度,
//然后如果长度大于等于k,我们开始交换节点,当k = 2时,每段我们只需要交换一次,
//当k = 3时,每段需要交换2此,所以i从1开始循环,注意交换一段后更新pre指针,然后num自减k
//直到num < k时循环结束,参见代码如下: //解法二:时间更长!!!! class Solution {
public:
ListNode* reverseKGroup(ListNode* head, int k) {
ListNode *dummy = new ListNode(-), *pre = dummy, *cur = pre;
dummy->next = head;
int num = ;
while (cur = cur->next) ++num;
while (num >= k) {
cur = pre->next;
for (int i = ; i < k; ++i) {
ListNode *t = cur->next;
cur->next = t->next;
t->next = pre->next;
pre->next = t;
}
pre = cur;
num -= k;
}
return dummy->next;
}
}; //我们也可以使用递归来做,我们用head记录每段的开始位置,cur记录结束位置的下一个节点,
//然后我们调用reverse函数来将这段翻转,然后得到一个new_head,原来的head就变成了末尾,
//这时候后面接上递归调用下一段得到的新节点,返回new_head即可,参见代码如下: class Solution {
public:
ListNode* reverseKGroup(ListNode* head, int k) {
ListNode *cur = head;
for (int i = ; i < k; ++i) {
if (!cur) return head;
cur = cur->next;
}
ListNode *new_head = reverse(head, cur);
head->next = reverseKGroup(cur, k);
return new_head;
}
ListNode* reverse(ListNode* head, ListNode* tail) {
ListNode *pre = tail;
while (head != tail) {
ListNode *t = head->next;
head->next = pre;
pre = head;
head = t;
}
return pre;
}
}; void T025() {
ListNode* N = new ListNode();
ListNode* p = N;
for (int i = ; i < ; ++i) {
ListNode* q = new ListNode();
q->val = i + ;
p->next = q;
p = q;
}
p = N->next;
cout << "原:";
while (p) {
cout << p->val << '\t';
p = p->next;
}
cout << endl;
Solution S;
p = S.reverseKGroup(N->next,);
cout << "转:";
while (p) {
cout << p->val << '\t';
p = p->next;
}
cout << endl; }

025k个一组翻转链表的更多相关文章

  1. [LintCode] Reverse Nodes in k-Group 每k个一组翻转链表

    Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. If ...

  2. leetcode 25. K 个一组翻转链表

    # coding:utf-8 __author__ = "sn" """ 25. K 个一组翻转链表 给你一个链表,每 k 个节点一组进行翻转,请你返 ...

  3. LeetCode 25. K 个一组翻转链表 | Python

    25. K 个一组翻转链表 题目来源:https://leetcode-cn.com/problems/reverse-nodes-in-k-group 题目 给你一个链表,每 k 个节点一组进行翻转 ...

  4. Java实现 LeetCode 25 K个一组翻转链表

    25. K 个一组翻转链表 给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表. k 是一个正整数,它的值小于或等于链表的长度. 如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持 ...

  5. LeetCoded第25题题解--K个一组翻转链表--java--链表

    链表 单链表:链表中的每个元素实际上是一个单独的对象,而所有对象都通过每个元素的引用字段链接在一起. 双链表:与单链表不同的是,双链表的每个节点都含有两个引用字段. 链表优点 灵活分配内存空间 能在O ...

  6. leetcode 24. 两两交换链表中的节点 及 25. K 个一组翻转链表

    24. 两两交换链表中的节点 问题描述 给定一个链表,两两交换其中相邻的节点,并返回交换后的链表. 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换. 示例: 给定 1->2-> ...

  7. LeetCode-025-K 个一组翻转链表

    K 个一组翻转链表 题目描述:给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表. k 是一个正整数,它的值小于或等于链表的长度. 如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保 ...

  8. [LeetCode] Reverse Nodes in k-Group 每k个一组翻转链表

    Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. If ...

  9. k个一组翻转链表(java实现)

    题目: 给出一个链表,每 k 个节点一组进行翻转,并返回翻转后的链表. k 是一个正整数,它的值小于或等于链表的长度.如果节点总数不是 k 的整数倍,那么将最后剩余节点保持原有顺序. 示例 : 给定这 ...

随机推荐

  1. Ansible常用模块介绍及使用(week5_day1_part2)--技术流ken

    Ansible模块 在上一篇博客<Ansible基础认识及安装使用详解(一)--技术流ken>中以及简单的介绍了一下ansible的模块.ansible是基于模块工作的,所以我们必须掌握几 ...

  2. Docker在Linux上运行NetCore系列(五)更新应用程序

    转发请注明此文章作者与路径,请尊重原著,违者必究. 本篇文章与其它系列文章不同,为了方便测试,新建了一个ASP.Net Core视图应用. 备注:下面说的应用,只是在容器中运行的应用程序. 查看现在运 ...

  3. 使用JS模拟锚点跳转

    A-HTML锚点定义: 设置锚: <a href="#mao">&nsbp;</a> 设置点:(为了浏览器兼容性,id和name一起设置) < ...

  4. H5 五子棋源码

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  5. MyBatis进阶使用——动态SQL

    MyBatis的强大特性之一就是它的动态SQL.如果你有使用JDBC或者其他类似框架的经验,你一定会体会到根据不同条件拼接SQL语句的痛苦.然而利用动态SQL这一特性可以彻底摆脱这一痛苦 MyBati ...

  6. 3;XHTML排列清单控制标记

    1.无序号条例式清单<ul> 2.有序号条例式清单<ol> 3.无序列表和有序列表的结合应用 4.叙述式清单<dl> 排列清单控制标记可以创建一般的列表.编号列表或 ...

  7. react-conponent-hellocynthia

    <!DOCTYPE html> <html> <head> <script src="../../build/react.js">& ...

  8. POJ 2311 Cutting Game(二维SG+Multi-Nim)

    Cutting Game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4798   Accepted: 1756 Desc ...

  9. BZOJ1101: [POI2007]Zap(莫比乌斯反演)

    1101: [POI2007]Zap Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2951  Solved: 1293[Submit][Status ...

  10. Markdown简单上手

    标题 # +内容 一级标题 二级标题 三级标题 四级标题 五级标题 六级标题 字体 1. 加粗(Ctrl+B) **加粗** 2. 斜体(Ctrl+I) *斜体* 3. 斜体加粗(Ctrl+B+I) ...