hard!

题目描述:

给出一个链表,每 个节点为一组进行翻转,并返回翻转后的链表。

是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 的整数倍,那么将最后剩余节点保持原有顺序。

示例 :

给定这个链表:1->2->3->4->5

当 = 2 时,应当返回: 2->1->4->3->5

当 = 3 时,应当返回: 3->2->1->4->5

说明 :

  • 你的算法只能使用常数的额外空间。
  • 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

解题思路:

这道题让我们以每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的位置更新到如下新的位置:

-->->->->->
| |
pre next -->->->->->
| |
pre next

以此类推,只要next走过k个节点,就可以调用翻转函数来进行局部翻转了。

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 || k == ) return head;
ListNode *dummy = new ListNode(-);
ListNode *pre = dummy, *cur = head;
dummy->next = head;
int i = ;
while (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;
ListNode *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时,每段需要交换两次,所以i从1开始循环,注意交换一段后更新pre指针,然后num自减k,直到num<k时循环结束。

C++解法二:

 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即可。

C++解法三:

 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;
}
};

LeetCode(15): 每k个一组翻转链表的更多相关文章

  1. 【LeetCode 25】K 个一组翻转链表

    题目链接 [题解] 模拟就好. 就k个k个节点地翻转. 每个节点都把next域指向它前面那个节点 修改完之后把这个节点前面的那个节点的next域改成这一段的最后一个节点. 然后把这一段最左边的那个节点 ...

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

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

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

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

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

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

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

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

  6. [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 ...

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

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

  8. [LeetCode]25. 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. k ...

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

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

  10. js 之k个一组翻转链表

    题目描述 将给出的链表中的节点每\ k k 个一组翻转,返回翻转后的链表如果链表中的节点数不是\ k k 的倍数,将最后剩下的节点保持原样你不能更改节点中的值,只能更改节点本身.要求空间复杂度 \ O ...

随机推荐

  1. Js单元测试工具 以及 粗浅的对我的快乐运算进行测试

    1. Karma的介绍 Karma是Testacular的新名字,在2012年google开源了Testacular,2013年Testacular改名为Karma.Karma是一个让人感到非常神秘的 ...

  2. Kafka与Logstash的数据采集对接

    Logstash工作原理 由于Kafka采用解耦的设计思想,并非原始的发布订阅,生产者负责产生消息,直接推送给消费者.而是在中间加入持久化层--broker,生产者把数据存放在broker中,消费者从 ...

  3. DataSet和实体类的相互转换

    最近做WInfrom项目,对表格和控件的数据绑定非常喜欢用实体类对象来解决,但是绑定以后 又怎么从控件中拿到实体类或者转换为datatable 或者dataset呢 经过在网上的搜索以及自己的改进 完 ...

  4. 我为什么放弃MySQL?选择了MongoDB

    最近有个项目的功能模块,为了处理方便,需要操作集合类型的数据以及其他原因.考虑再三最终决定放弃使用MySQL,而选择MongoDB. 两个数据库,大家应该都不陌生.他们最大的区别就是MySQL为关系型 ...

  5. Lua 调试库

    Lua 调试库 http://blog.csdn.net/vermilliontear/article/details/50851045 http://blog.csdn.net/vermillion ...

  6. R vs Python,数据分析中谁与争锋?

    R和Python两者谁更适合数据分析领域?在某些特定情况下谁会更有优势?还是一个天生在各方面都比另一个更好? 当我们想要选择一种编程语言进行数据分析时,相信大多数人都会想到R和Python——但是从这 ...

  7. bzoj1038

    这是一道非常有意思的题目 Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们将H村抽象为一维的轮廓.如下图所示 我们可以用一 ...

  8. dp乱写2:论dp在不在dp中(但在dp范畴)内的应用

    最近正儿八经的学习了dp,有一些题目非常明显看出来就是dp了比如说:过河卒.方格取数.导弹拦截.加分二叉树.炮兵阵地更加明显的还有:采药.装箱问题.过河.金明的预算方案.今天来谈谈dp的dp在不在dp ...

  9. Winform Treeview 的按需加载

    最近项目里用到treeview,原先设计的是一开始就把所有数据都加载到treeview里,后来发现客户的数据量实在太大,加载所有数据要2分钟,这个是客户没法接受的.后来就考虑到用户也不是一开始就要看所 ...

  10. 函数和常用模块【day04】:内置函数分类总结(十一)

    重点掌握 字符串格式化format() 字符串格式化百分号 判断 转换 数据类型 帮助信息 map和filter()函数 局部变量全局变量 计算内置函数 常用内置函数(其他) 后续会讲 不常用