Reverse Nodes in k-Group

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

If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.

You may not alter the values in the nodes, only nodes itself may be changed.
Only constant memory is allowed.
For example,
Given this linked list: 1->2->3->4->5
For k = 2, you should return: 2->1->4->3->5
For k = 3, you should return: 3->2->1->4->5
 
 
SOLUTION 1
用递归实现,逐层进行反转。遇到最后一个如果个数不为k,再反转一次即可。
 /*
SOLUTION 2: A better rec version.
*/
public ListNode reverseKGroup2(ListNode head, int k) {
if (head == null) {
return null;
} return rec2(head, k);
} public ListNode rec2(ListNode head, int k) {
if (head == null) {
return null;
} ListNode dummy = new ListNode(0); ListNode cur = head;
int cnt = 0;
while (cur != null) {
ListNode tmp = cur.next;
cur.next = dummy.next;
dummy.next = cur; cur = tmp; cnt++; // reverse a k group.
if (cnt == k) {
// BUG 1:
head.next = rec2(tmp, k);
return dummy.next;
}
} // we don't have k nodes.
if (cnt != k) {
cur = dummy.next;
dummy.next = null; // reverse again.
while (cur != null) {
ListNode tmp = cur.next;
cur.next = dummy.next;
dummy.next = cur; cur = tmp;
}
} return dummy.next;
}

SOLUTION 2

另一个思路的递归:

先查看有没有k个node,如果有,切开2个链表,反转当前链表,并且使用递归处理下一个section,最后再把2者连接起来即可。

 public ListNode reverseKGroup1(ListNode head, int k) {
if (head == null) {
return null;
} return rec(head, k);
} // Solution 1: Recursion.
public ListNode rec(ListNode head, int k) {
// Reverse k and link to the next section.
ListNode dummy = new ListNode(0);
dummy.next = head; // find the tail node of the section. If not find, just return.
int cnt = k;
ListNode tail = dummy;
while (cnt > 0 && tail != null) {
cnt--;
tail = tail.next;
} // We don't have k nodes to revers.
// bug 1: we should judge that if tail == null to avoid the overflow.
if (tail == null) {
return head;
} // cut the 2 list.
ListNode next = tail.next;
tail.next = null; // reverse the first list.
ListNode newHead = reverse(head); // reverse the next section.
next = rec(next, k); // link the 2 sections.
head.next = next; return newHead;
} public ListNode reverse(ListNode head) {
ListNode dummy = new ListNode(0);
while (head != null) {
ListNode tmp = head.next;
head.next = dummy.next;
dummy.next = head; head = tmp;
} return dummy.next;
}

SOLUTION 3

使用一个专用的反转函数来进行反转,从头到尾遍历,遍历到K的时候,使用Pre-Next指针的方式进行反转。这个方法比递归更棒。

要特别注意的是:

reverseSection 函数中,while 循环的终止条件不是cur != null,而是cur != next。这一点要特别注意,否则很容易造成死循环!

// BUG: Severe. if we use cur != null here, we will cause very serious loop error.
while (cur != next) {
   ...
}

 /*
SOLUTION 3: A Iteration version.
*/
public ListNode reverseKGroup(ListNode head, int k) {
if (head == null) {
return null;
} ListNode dummy = new ListNode(0);
dummy.next = head; ListNode pre = dummy;
ListNode cur = pre.next; int cnt = 0;
while (cur != null) {
cnt++;
cur = cur.next; if (cnt == k) {
cnt = 0;
pre = reverseSection(pre, cur);
cur = pre.next;
}
} return dummy.next;
} /**
* Reverse a link list between pre and next exclusively
* an example:
* a linked list:
* 0->1->2->3->4->5->6
* | |
* pre next
* after call pre = reverse(pre, next)
*
* 0->3->2->1->4->5->6
* | |
* pre next
* @param pre
* @param next
* @return the reversed list's last node, which is the precedence of parameter next
*/
private static ListNode reverseSection(ListNode pre, ListNode next){
ListNode cur = pre.next; // record the new tail.
ListNode tail = cur; // BUG: Severe. if we use cur != null here, we will cause very serious loop error.
while (cur != next) {
ListNode tmp = cur.next;
cur.next = pre.next;
pre.next = cur;
cur = tmp;
} tail.next = next;
return tail;
}

GITHUB:

1. 主页君的GitHub代码

2. 2014.1227 Redo:

https://github.com/yuzhangcmu/LeetCode_algorithm/blob/master/list/ReverseKGroup_1227_2014.java

ref: http://www.cnblogs.com/lichen782/p/leetcode_Reverse_Nodes_in_kGroup.html

LeetCode: Reverse Nodes in k-Group 解题报告的更多相关文章

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

  2. 【LeetCode】402. Remove K Digits 解题报告(Python)

    [LeetCode]402. Remove K Digits 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http: ...

  3. LeetCode: Reverse Words in a String 解题报告

    Reverse Words in a String Given an input string, reverse the string word by word. For example,Given ...

  4. Reverse Nodes In K Group,将链表每k个元素为一组进行反转---特例Swap Nodes in Pairs,成对儿反转

    问题描述:1->2->3->4,假设k=2进行反转,得到2->1->4->3:k=3进行反转,得到3->2->1->4 算法思想:基本操作就是链表 ...

  5. 【LeetCode】743. Network Delay Time 解题报告(Python)

    [LeetCode]743. Network Delay Time 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: ht ...

  6. 【LeetCode】Pascal's Triangle II 解题报告

    [LeetCode]Pascal's Triangle II 解题报告 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/problems/pascals-tr ...

  7. 【LeetCode】785. Is Graph Bipartite? 解题报告(Python)

    [LeetCode]785. Is Graph Bipartite? 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu. ...

  8. 【LeetCode】732. My Calendar III解题报告

    [LeetCode]732. My Calendar III解题报告 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/problems/my-calendar ...

  9. 【LeetCode】764. Largest Plus Sign 解题报告(Python)

    [LeetCode]764. Largest Plus Sign 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn ...

  10. 【LeetCode】851. Loud and Rich 解题报告(Python)

    [LeetCode]851. Loud and Rich 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http:// ...

随机推荐

  1. 是否只查看安全传送的网页内容? 去掉 IE弹出窗口

    选择IE工具intemt选项,在选项卡里选择安全,然后在安全选项卡里点自定义级别,在设置里找到‘其他’这个分类,在次分类下找到‘显示混合内容’选择‘启用’然后保存退出就OK了,当然楼上几位说安全问题, ...

  2. memcached内存管理机制[未整理]

    memcached默认采用的是Slab Allocator的机制分配管理内存的,在此之前,内存的分配是通过对所有的记录简单地进行malloc和free来进行的,但这种方式容易造成很多内存碎片,加重操作 ...

  3. 基本的RAID介绍

    RAID是一个我们经常能见到的名词.但却因为很少能在实际环境中体验,所以很难对其原理 能有很清楚的认识和掌握.本文将对RAID技术进行介绍和总结,以期能尽量阐明其概念. RAID全称为独立磁盘冗余阵列 ...

  4. Redis 学习之路 (009) - Redis-cli命令最新总结

    资料来源: http://redisdoc.com/ http://redis.io/commands 连接操作相关的命令 默认直接连接  远程连接-h 192.168.1.20 -p 6379 pi ...

  5. git学习笔记(四)—— 分支管理

    一.创建与合并分支 git branch //查看分支 git branch <name> //创建分支 git checkout <name> //切换分支 git chec ...

  6. Scala学习网址

    scala学习网址为:https://twitter.github.io/scala_school/zh_cn https://www.zhihu.com/question/26707124

  7. spring cloud 之 Feign 使用HTTP请求远程服务

    一.Feign 简介 在spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端.我们可以使用JDK原生的URLCo ...

  8. [aaronyang原创] Mssql 一张表3列的sql面试题,看你sql学的怎么样

    文章已经迁移到:http://www.ayjs.net/post/99.html 文章已经迁移到:http://www.ayjs.net/post/99.html 文章已经迁移到:http://www ...

  9. MongoDB学习笔记(3)--删除数据库

    MongoDB 删除数据库 语法 MongoDB 删除数据库的语法格式如下: db.dropDatabase() 删除当前数据库,默认为 test,你可以使用 db 命令查看当前数据库名. 实例 以下 ...

  10. 面向对象的Shell脚本

    还记得以前那个用算素数的正则表达式吗?编程这个世界太有趣了,总是能看到一些即别出心裁的东西.你有没有想过在写Shell脚本的时候可以把你的变量和函数放到一个类中?不要以为这不可能,这不,我在网上又看到 ...