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. Nginx 504 Gateway Time-out问题解决

    今天站群VPS上面的所有站出现的 504 网关错误,现在小色还是菜菜的,斗胆解决下.在网上面搜解决方案,尝试设置ngxin的fast-cgi_buffers 和重启ngxin来解决,但是错误依旧.怀疑 ...

  2. NBUT [1475] Bachelor

    [1475] Bachelor http://acm.nbut.cn:8081/Problem/view.xhtml?id=1475 时间限制: 1000 ms 内存限制: 65535 K 问题描述 ...

  3. iscsi target 之LIO配置

    LIO 配置 现在主流Linux都可以设置iSCSI,如STGT/TGT.LIO Target等.Linux-IO(LIO)Target是当前Linux标准的iSCSI target的开源实现,包含在 ...

  4. iOS 11和xcode9

    最近发现了比较奇怪的问题,就是 ios10.几以前的版本,用xcode9 编写的程序   如果程序写的table是  plain的  ,那么  在  ios10.几及以下版本都会显示成group样式, ...

  5. Git 配置(分布式版本控制系统)

    1.Mac Git 配置文件 既然已经在系统上安装了 Git,你会想要做几件事来定制你的 Git 环境.每台计算机上只需要配置一次,程序升级时会保留配置信息.你可以在任何时候再次通过运行命令来修改它们 ...

  6. mysql主从复制配置问题

    一,基本步骤 1,创建在主从数据上都创建复制账号,权限选上super, replication slave , replication master(选上这个可以方便从库变成主库): 2,配置主库和备 ...

  7. “21天教你学会C++”

    下面是一个<Teach Yourself  C++ in 21 Days>的流程图,请各位程序员同仁认真领会.如果有必要,你可以查看这个图书以作参照:http://www.china-pu ...

  8. centos中添加php扩展pdo_mysql步骤

    本文内容是以 CentOS 为例,红帽系列的 Linux 方法应该都是如此,下面就详细说明步骤,在这里严重鄙视哪些内容??隆⑺档脑悠咴影说挠泄 PDO 编译安装的文章. 1.进入 PHP 的软件包 p ...

  9. 深入理解Python中的yield和send

    send方法和next方法唯一的区别是在执行send方法会首先把上一次挂起的yield语句的返回值通过参数设定,从而实现与生成器方法的交互. 但是需要注意,在一个生成器对象没有执行next方法之前,由 ...

  10. 转 kafka架构简介

    kafka架构 转 http://www.cnblogs.com/chushiyaoyue/p/5612298.html 相关文章: https://www.jianshu.com/p/6233d53 ...