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;
  }
};
目录
相关文章
|
1月前
【LeetCode 09】19 删除链表的倒数第 N 个结点
【LeetCode 09】19 删除链表的倒数第 N 个结点
16 0
|
3月前
|
算法
LeetCode第19题删除链表的倒数第 N 个结点
该文章介绍了 LeetCode 第 19 题删除链表的倒数第 N 个结点的解法,通过使用快慢双指针,先将快指针移动 n 步,然后快慢指针一起遍历,直到快指针到达链尾,从而找到倒数第 N 个结点的前一个结点进行删除,同时总结了快慢指针可减少链表遍历次数的特点。
LeetCode第19题删除链表的倒数第 N 个结点
|
4月前
|
存储 C++
C++的list-map链表与映射表
```markdown C++ 中的`list`和`map`提供链表和映射表功能。`list`是双向链表,支持头尾插入删除(`push_front/push_back/pop_front/pop_back`),迭代器遍历及任意位置插入删除。`map`是键值对集合,自动按键排序,支持直接通过键来添加、修改和删除元素。两者均能使用范围for循环遍历,`map`的`count`函数用于统计键值出现次数。 ```
|
5月前
|
存储 C++
C++的list-map链表与映射表
这篇教程介绍了C++中`list`链表和`map`映射表的基本使用。`list`链表可通过`push_front()`、`push_back()`、`pop_front()`和`pop_back()`进行元素的添加和删除,使用迭代器遍历并支持在任意位置插入或删除元素。`map`是一个键值对的集合,元素自动按键值排序,可使用下标操作符或`insert()`函数插入元素,通过迭代器遍历并修改键值对,同时提供`count()`方法统计键值出现次数。教程中包含多个示例代码以帮助理解和学习。
|
5月前
|
C++ 容器
【C++进阶】深入STL之list:高效双向链表的使用技巧
【C++进阶】深入STL之list:高效双向链表的使用技巧
59 0
|
5月前
|
存储 NoSQL Redis
Redis第四弹,Redis实现list时候做出的优化ziplist(压缩链表,元素少的情况),可更好的节省空间list——(内部编码:quicklist)Object encoding
Redis第四弹,Redis实现list时候做出的优化ziplist(压缩链表,元素少的情况),可更好的节省空间list——(内部编码:quicklist)Object encoding
|
6月前
|
存储 Python
链表(Linked List)详解
链表(Linked List)详解
50 0
|
6月前
题目----力扣--链表的中间结点
题目----力扣--链表的中间结点
28 0
|
6月前
|
索引
【力扣刷题】删除链表的倒数第 N 个结点、两两交换链表中的节点、随机链表的复制
【力扣刷题】删除链表的倒数第 N 个结点、两两交换链表中的节点、随机链表的复制
35 0
|
5月前
|
存储 SQL 算法
LeetCode力扣第114题:多种算法实现 将二叉树展开为链表
LeetCode力扣第114题:多种算法实现 将二叉树展开为链表