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. Linux 操作MySQL常用命令行(转)

    注意:MySQL中每个命令后都要以分号:结尾. 1.显示数据库 mysql> show databases; +----------+ | Database | +----------+ | m ...

  2. DMA直接内存存取原理

    DMA是指外部设备不通过CPU而直接与系统内存交换数据的接口技术. 要把外设的数据读入内存或把内存的数据传送到外设,一般都要通过CPU控制完成,如CPU程序查询或中断方式.利用中断进行数据传送,可以大 ...

  3. VS2010调试多进程

    http://msdn.microsoft.com/zh-cn/library/ms123401.aspx 选择启动项目 在“解决方案资源管理器”中,右击项目名,然后在快捷菜单上单击“设为启动项目”. ...

  4. Tensorflow 相关概念

    一.概述 人工智能:artificial intelligence 权重: weights 偏差:biases 图中包含输入( input).塑形( reshape). Relu 层( Relulay ...

  5. 【Eclipse】Eclipse上如何集成SVN插件

    SVN的安装 下载svn插件site.zip工具包 解压site工具包,将内容放置到eclipse\dropins目录下 重启 eclipse 打开 SVN 窗口 提示:如果 SVN 图标出现红色方块 ...

  6. MYSQL内存评估

    ### MySQL Memory Calculator Procedure ### http://kedar.nitty-witty.com/blog/calculte-mysql-memory-us ...

  7. python selenium expected_conditions使用实例

    今天正好虫师问到selenium python binding中support.expected_conditions的用法,顺手总结了一下,希望对大家有所帮助. 场景 Expected Condit ...

  8. SharePoint 中时间轴 Timeline的实现

    客户需要在OA中实现每日动态功能,能够记录每一位员工的每天的工作动态,我很快想到了时间轴,因为时间轴能很直观的现实员工每一刻的动态.就像Facebook的Timeline效果(点击查看). 尝试着搜索 ...

  9. TCP握手和传输的一次观察

    1. TCP三次握手SYN ---> <--- SYN,ACKACK ---> 花费时间:386.718-385.784=0.934ms 2.正常的消息交互2.1. 服务器主动校验 ...

  10. 用SQL语句将远程SQL Server数据库中表数据导入到本地数据库相应的表中

    一.方法一 访问不同电脑上的数据库(远程访问,只好联好网就一样),如果经常访问或数据量较大,建议用链接服务器方法. 1.创建链接服务器 exec sp_addlinkedserver ‘srv_lnk ...