热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

个人记录LeetCode25.ReverseNodesinkGroup

问题:Givenalinkedlist,reversethenodesofalinkedlistkatatimeandreturnitsmodifiedlist.I

问题:
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个节点,我们定义prev、begin、end和nextBegin这几个指针。
如图所示,含义还是很清晰的,不作赘述。

在开始时,将prev的next变为end。
然后,定义一个move指针,从begin开始移动到end的前一个节点。
于是end的next指向move。

end前移到move的位置。
move又从begin开始,移动到end的前一个节点。
再次进行与上面一样的修改。

直到,end移动到begin的后面。
此时,将end的next修改为begin。
begin的next修改为nextBegin,begin将作为后续连续K个节点的Prev。

以上方法并不是最快的,但占用的内存是常数级的(只用到了引用),满足要求。
当然,实际上我这里从最后开始逆着修改next,比较耗时。

从前往后修改也是可以的,只用一个引用保存下一个要修改的节点即可。

代码示例:
1、逆着修改next

/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/
public class Solution {public ListNode reverseKGroup(ListNode head, int k) {if (head &#61;&#61; null || k <&#61; 1) {return head;}ListNode temp &#61; head;int len &#61; 0;//先判断长度够不够while (temp !&#61; null) {&#43;&#43;len;if (len &#61;&#61; k) {break;}temp &#61; temp.next;}if (len !&#61; k) {return head;}//初始时prev为nullListNode prev &#61; null;ListNode begin &#61; head;//长度够的话&#xff0c;最终的头为此时的第K个节点head &#61; temp;while (begin !&#61; null) {//每次操作前&#xff0c;记录当前的begin&#xff0c;这是下一次的prevListNode lastBegin &#61; begin;begin &#61; reverseKGroupInternal(prev, begin, k);prev &#61; lastBegin;}return head;}private ListNode reverseKGroupInternal(ListNode prev, ListNode begin, int k) {ListNode temp &#61; begin;ListNode end &#61; null;ListNode nextBegin &#61; null;int len &#61; 0;//同样需要判断此次操作的长度是否满足条件while (temp !&#61; null) {&#43;&#43;len;if (len &#61;&#61; k) {//得到本次操作的end及nextBeginend &#61; temp;nextBegin &#61; end.next;break;}temp &#61; temp.next;}if (len !&#61; k || end &#61;&#61; null) {return null;}//prev的next指向endif (prev !&#61; null) {prev.next &#61; end;}ListNode move;while (begin.next !&#61; end) {//移动move到end的前面move &#61; begin;while (move.next !&#61; end) {move &#61; move.next;}//end的next指向moveend.next &#61; move;//前移endend &#61; move;}//最后时刻&#xff0c;end刚好在begin后面//修改end.next指向beginend.next &#61; begin;//begin.next指向nextBeginbegin.next &#61; nextBegin;return nextBegin;}
}

2、基本逻辑与上面一致&#xff0c;就是顺着改next

/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val &#61; x; }* }*/
public class Solution {public ListNode reverseKGroup(ListNode head, int k) {if (head &#61;&#61; null || k <&#61; 1) {return head;}ListNode temp &#61; head;int len &#61; 0;while (temp !&#61; null) {&#43;&#43;len;if (len &#61;&#61; k) {break;}temp &#61; temp.next;}if (len !&#61; k) {return head;}ListNode prev &#61; null;ListNode begin &#61; head;head &#61; temp;while (begin !&#61; null) {ListNode lastBegin &#61; begin;begin &#61; reverseKGroupInternal(prev, begin, k);prev &#61; lastBegin;}return head;}private ListNode reverseKGroupInternal(ListNode prev, ListNode begin, int k) {ListNode temp &#61; begin;ListNode end &#61; null;ListNode nextBegin &#61; null;int len &#61; 0;while (temp !&#61; null) {&#43;&#43;len;if (len &#61;&#61; k) {end &#61; temp;nextBegin &#61; end.next;break;}temp &#61; temp.next;}if (len !&#61; k || end &#61;&#61; null) {return null;}if (prev !&#61; null) {prev.next &#61; end;}ListNode first &#61; begin;ListNode second &#61; begin.next;begin.next &#61; nextBegin;//只有下面这部分存在差异while(second !&#61; null && second !&#61; end) {ListNode local &#61; second.next;second.next &#61; first;first &#61; second;second &#61; local;}if (second !&#61; null) {second.next &#61; first;}return nextBegin;}
}

在前文的基础上&#xff0c;可以进一步优化每一段逆转的逻辑&#xff0c;即每一段轮询的同时完成逆转&#xff1a;

class Solution {public ListNode reverseKGroup(ListNode head, int k) {if (head &#61;&#61; null || k <&#61; 1) {return head;}ListNode ret &#61; head;ListNode pre &#61; null;ListNode nextBegin;ListNode begin &#61; head;ListNode end &#61; begin;while (begin !&#61; null) {int count &#61; 1;while(count }


推荐阅读
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • 本文介绍了C++中省略号类型和参数个数不确定函数参数的使用方法,并提供了一个范例。通过宏定义的方式,可以方便地处理不定参数的情况。文章中给出了具体的代码实现,并对代码进行了解释和说明。这对于需要处理不定参数的情况的程序员来说,是一个很有用的参考资料。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 本文介绍了UVALive6575题目Odd and Even Zeroes的解法,使用了数位dp和找规律的方法。阶乘的定义和性质被介绍,并给出了一些例子。其中,部分阶乘的尾零个数为奇数,部分为偶数。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
author-avatar
华华eva3
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有