朋友出了一道题,最近在写解法的时候发现还有点意思,索性记一下,问题如下图(https://leetcode.com/problems/rotate-list/):
思路:
1、关于这一题,很明显不可能采用一步一步的去挪,算法的空间复杂度太高
2、总要的是如何标记到需要改变的节点的位置,由于还需要操作链表的指向,而此链表的数据结构是单向链表,所以也就是新列表的头节点(listNode)的上一个(previous)
因此,我的第一个写法是
朋友看过后说了一句,采用递归会减少效率(虽然我对于这一题,我并不觉得有多大损失╮(╯_╰)╭),改为无递归的version
此版本添加了一个preHead节点,用来便于记录节点的。大致思路就是
异常控制1(空list和k值小于最小挪动步数,返回原list)
遍历节点,记录与当前节点和k+1的前一个节点
异常控制2 (list长度为1,返回原list)
如果k > listLen,用k%listLen找目标节点,操作列表,返回结果
如果k < listLen, 则k+1的前一个节点为目标节点,操作列表,返回结果
之后,看了一下高票的答案(https://leetcode.com/problems/rotate-list/discuss/22735/My-clean-C%2B%2B-code-quite-standard-(find-tail-and-reconnect-the-list)),感觉这句话“ Some people used slow/fast pointers to find the tail node but I don't see the benefit (in the sense that it doesn't reduce the pointer move op) to do so. ”说的挺不错的,即使对于example1,由于temp指针的挪动,实际操作数并未减少太多,因此,再修改了一下代码,如下
PS1: 代码链接
PS2: 高票答案的节点操作真的是赞