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

题意:以k个结点为一组,进行反转连接,若最后小于k个结点,则保持不变。要求:仅用常数空间,不改变结点的值。

思路:大致过程是每k个结点一反转,直到剩余结点数小于k。遇到一个问题是:如何判断剩余结点数小于k,即循环的终止条件?这样就需要知道整条链表的总共的结点数count,然后每次反转完一组则用总的count减去k,直到最后剩余结点数小于k,就不用改变。遇到另一个问题,如何反转k个结点,这个和reverse linked list ii类似,大致的想法可以参照。这样就剩下的如何将不同的小组连接起来的问题,因为在reverse linked list ii这题中,只要反转一部分,所以其pre是不动的,这题因为有很多小组,所以pre应该是每k个结点为一小组的最开始结点的前驱,所以要移动,同理的是当前节点cur。因为要改变表头,所以要先new一个nList。使用计数器的思维值得注意。

 /**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *reverseKGroup(ListNode *head, int k)
{
ListNode *nList=new ListNode(-);
nList->next=head;
ListNode *cur=head;
ListNode *pre=nList; int num=; //组里的结点数
int count=; //整链结点数
while(head)
{
head=head->next;
count++;
} while(count>=k) //整体遍历
{
while(++num<k) //组内循环
{
ListNode *temp=cur->next;
cur->next=temp->next;
temp->next=pre->next;
pre->next=temp;
}
count-=num;  //减k也行.
num=;
pre=cur; //每组反转以后,pre要移动
cur=cur->next; //cur要变
}
return nList->next; }
};

还有另一种写法:见Code Gander的博客,其核心思想是,每次取k个结点进行反转,传入反转函数的是这个组的前驱和其最后一个结点,反转函数返回是反转后小组的第一个结点,体会其中的差别。代码如下:

 /**   Reverse Nodes in k-Group
*
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/ //经典,很多关于list的题都可用这种方法重写
/* 使用计数器count,若count=k,则反转前k个节点,然后重置count */
class Solution {
public:
ListNode *reverseKGroup(ListNode *head, int k)
{
if(head==NULL) return NULL; ListNode *preAll=new ListNode(-);
preAll->next=head; ListNode *pre=preAll;
ListNode *cur=head;
int count=; while(cur !=NULL)
{
count++;
ListNode *last=cur->next;
if(count==k)
{
pre=reverse(pre,last);
count=;
}
cur=last;
} return preAll->next;
} //反转前k个节点,这k个点的前驱和最后一点传入
ListNode *reverse(ListNode *pre,ListNode *last)
{
if(pre==NULL||pre->next==NULL) return pre; ListNode *head=pre->next;
ListNode *cur=pre->next->next; while(cur !=last)
{
ListNode *temp=cur->next;
cur->next=pre->next;
pre->next=cur;
cur=temp;
} head->next=last;
return head; //巧妙之处是返回前节点
}
};

[Leetcode] Reverse nodes in k group 每k个一组反转链表的更多相关文章

  1. 如何k个一组反转链表

    之前的文章「递归反转链表的一部分」讲了如何递归地反转一部分链表,有读者就问如何迭代地反转链表,这篇文章解决的问题也需要反转链表的函数,我们不妨就用迭代方式来解决. 本文要解决「K 个一组反转链表」,不 ...

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

  3. 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 ...

  4. 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. k  ...

  5. LeetCode Reverse Nodes in k-Group 每k个节点为一组,反置链表

    题意:给一个单链表,每k个节点就将这k个节点反置,若节点数不是k的倍数,则后面不够k个的这一小段链表不必反置. 思路:递归法.每次递归就将k个节点反置,将k个之后的链表头递归下去解决.利用原来的函数接 ...

  6. LeetCode: Reverse Nodes in k-Group 解题报告

    Reverse Nodes in k-Group Given a linked list, reverse the nodes of a linked list k at a time and ret ...

  7. Leetcode 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 ...

  8. leetcode Reverse Nodes in k-Group python

    # Definition for singly-linked list. # class ListNode(object): # def __init__(self, x): # self.val = ...

  9. 【Reverse Nodes in k-Group】cpp

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

随机推荐

  1. 如何用 npm 同时执行两条监听命令

    在日常项目中启动项目 需要启动项目可能需要不止一条命令 这就很麻烦 要开启两个bash 很麻烦 终于找到了比较好的解决方案 例如我的: npm run dev //启动项目项目 npm run jso ...

  2. rails中如何在a标签中添加其他标签

    最近在用rails写一个项目练练手,然后遇到了一个问题,就是用 <% link_to("首页", root_path) %> 生成一个a标签,之后就在想我怎么在这个a标 ...

  3. 自定义vim配置文件vimrc,用于c/c++编程

    vim作为Linux下广受赞誉的代码编辑器,其独特的纯命令行操作模式可以很大程度上方便编程工作,通过自定义vim配置文件可以实现对vim功能的个性化设置. vim配置文件一般有两份,属于root的/e ...

  4. dot安装和使用

    1.安装 apt-get install graphviz 如果报错说缺少依赖文件,则使用apt自动安装依赖项 apt-get -f install 我在安装中报错: dpkg: unrecovera ...

  5. linux课后作业1

    本实验6第一题:菜单驱动程序. 随便进到某个目录,vim driver.sh 把代码写进去. #!/bin/bash function welcome() { echo -e "\n&quo ...

  6. AVL重平衡细节——插入

    话说这个系列鸽了好久,之前在准备语言考试,就没管博客了,现在暑假咱们继续上路! 每当我们进行一次插入之后,整棵AVL树的平衡性就有可能发生改变,为了控制整棵树的高度,我们需要通过一系列变换(重平衡)来 ...

  7. Date()日期函数浏览器兼容问题踩坑

    原文:Date()日期函数浏览器兼容问题踩坑 之前用layui做的一项目中,table中用到了日期格式化的问题.直接没多想,撸代码就完了呗,结果最近一段时间客户反馈说显示日期跟录入日期不一样(显示日期 ...

  8. 完整的vue+vuex+api-router+database请求流程

  9. OrCAD创建原理图符号图

    1. 首先创建一个库 2. 右键新创建的库,添加新的器件New Part 3. 修改器件属性 4. 添加引脚 添加完引脚之后如图,其中双击引脚,即可修改引脚名字和序号 5. 添加符号的外形 添加完外形 ...

  10. guacamole实现剪切复制

    主要功能是实现把堡垒机的内容复制到浏览器端,把浏览器端的文本复制到堡垒机上. 借助一个中间的文本框,现将堡垒机内容复制到一个文本框,然后把文本框内容复制出来.或者将需要传递到堡垒机的内容先复制到文本框 ...