LeetCode 25 Reverse Nodes in k-Group(在K组链表中反转结点)(Linked List)(*)

简介: 版权声明:转载请联系本人,感谢配合!本站地址:http://blog.csdn.net/nomasp https://blog.csdn.net/NoMasp/article/details/49815131 原文给定一个链表,在一定时间内反转这个链表的结点,并返回修改后的链表。
版权声明:转载请联系本人,感谢配合!本站地址:http://blog.csdn.net/nomasp https://blog.csdn.net/NoMasp/article/details/49815131

原文

给定一个链表,在一定时间内反转这个链表的结点,并返回修改后的链表。

如果结点数不是K的倍数,那么剩余的结点就保持原样。

你不应该在结点上修改它的值,只有结点自身可以修改。

只允许使用常量空间。

例如

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

对于 k = 2,你应该返回: 2->1->4->3->5

对于 k = 3,你应该返回: 3->2->1->4->5

翻译

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

分析

updated at 2016/08/14

题目要求是每K个节点进行一次逆序,不足K个节点不进行逆序。

那么,这个问题可以分解成2个小问题:
1,找出这里所有的“每K个节点”,如何找?
2,对这K个节点进行局部的逆序,怎么逆?

其实都不难,我们拆分成小问题就好解决了。

比如说K等于3,链表如下:

1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> NULL

设当前节点为current,其在1上,再走K-1步,到达3,这时候将其用reverse函数进行局部逆序,怎么逆?先不管,抽象出来。这时候链表如下:

3 -> 2 -> 1 -> 4 -> 5 -> 6 -> 7 - > NULL

之前我们的head是在1上,现在局部逆序之后,它就在1上了。这时候我们使用

head->next = reverseKGroup(start, k);

这里的start也就是即将第二次开始逆序时的head,也就是我所示链表中的4。关键一点是通过这一步,将其作为递归不断的进行下去。

是个递归都要有终止的条件,这里的条件是什么?

只要后续链表中的节点能够大于或等于K,我们就得将局部逆序进行下去,那么如果小于K呢?那自然就不用进行下去了,返回当前的head。什么样叫进行不下去呢,当前current为NULL的时候。

对于我举的例子,当第二次逆序完成后,head是4(6 -> 5 -> 4),start是7。我们就将7(这个序列的头部head)返回作为head(当前是4)的next。

Ok,第一个问题解决了,第二个问题,局部逆序。

前面曾有篇文章介绍过逆序: LeetCode 206 Reverse Linked List(反转链表)(Linked List)(四步将递归改写成迭代)(*)

ListNode* reverseList(ListNode* head) {
  ListNode* newHead = NULL;
  while (head) {
    ListNode* nextNode = head->next;
    head->next = newHead;
    newHead = head;
    head = nextNode;
  }
  return newHead;
}

这是递归的版本,如果要用迭代的可以去看看这篇博客,正好还讲了如何将递归改写成迭代。

现在这个版本是将整个链表进行逆序,如果想要局部的逆序,其实很简单。通过观察我们发现,这里的结束条件,是head为空的时候,也就是到最后一个节点了,如果我们将其条件改成

while (start != end)

因为start(也就是上面代码中的head)会一直往后走,所以肯定会等于end,这时候递归就停止了,问题也就解决了。

代码

class Solution {
public:
  ListNode* reverseKGroup(ListNode *head, int k) {
    ListNode *current = head;
    for (int i = 0; i < k; ++i) {
      if (!current) return head;
      current = current->next;
    }
    ListNode *newHead = reverse(head, current);
    head->next = reverseKGroup(current, k);
    return newHead;
  }

  ListNode* reverse(ListNode *start, ListNode *end) {
    ListNode *head = end;
    while (start != end) {
      ListNode *tmp = start->next;
      start->next = head;
      head = start;
      start = tmp;
    }
    return head;
  }
};
目录
相关文章
【移除链表元素】LeetCode第203题讲解
【移除链表元素】LeetCode第203题讲解
|
10天前
【力扣】21. 合并两个有序链表
【力扣】21. 合并两个有序链表
|
1月前
|
存储 JavaScript
leetcode82. 删除排序链表中的重复元素 II
leetcode82. 删除排序链表中的重复元素 II
22 0
|
1月前
leetcode83. 删除排序链表中的重复元素
leetcode83. 删除排序链表中的重复元素
10 0
|
1月前
leetcode2807.在链表中插入最大公约数
leetcode2807.在链表中插入最大公约数
16 0
|
1月前
|
算法
LeetCode刷题---19. 删除链表的倒数第 N 个结点(双指针-快慢指针)
LeetCode刷题---19. 删除链表的倒数第 N 个结点(双指针-快慢指针)
|
1月前
|
存储
LeetCode刷题---817. 链表组件(哈希表)
LeetCode刷题---817. 链表组件(哈希表)
|
1月前
|
存储 C语言 索引
环形链表、环形链表 II、有效的括号​​​​​​​【LeetCode刷题日志】
环形链表、环形链表 II、有效的括号​​​​​​​【LeetCode刷题日志】
|
1月前
|
算法 安全 数据处理
LeetCode刷题---707. 设计链表(双向链表-带头尾双结点)
LeetCode刷题---707. 设计链表(双向链表-带头尾双结点)
|
1月前
|
存储 算法
LeetCode刷题--- 61. 旋转链表(快慢指针+闭合为环)
LeetCode刷题--- 61. 旋转链表(快慢指针+闭合为环)

热门文章

最新文章