题目描述
给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。
示例 1:
输入:head = [1,2,3,4,5], k = 2 输出:[4,5,1,2,3] 示例 2:
输入:head = [0,1,2], k = 4 输出:[2,0,1]
提示:
链表中节点的数目在范围 [0, 500] 内 -100 <= Node.val <= 100 0 <= k <= 2 * 109
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/ro… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
说,要把大象装冰箱,拢共分几步? 要让一个单链表转起来,我们可以想象成一个环形链表,以钟表为模型,以头结点为顶端(12点钟),让链表顺时针转动k次得出新的链表,转动后的新的12点的位置就是新链表的头部,而新头部的上一个节点应该为新链表的尾部,我们只需要将新的尾部与新的头部断开,那新的单链表即为目标链表。
- 初始链表
2. 穿成环后
3. 顺时针移动k下,k=2
我们发现,转动两次后,原来的4号位变成了目标链表的头结点,而3号位应该变成目标链表的尾结点,我们需要将3号位断开,假设链表的长度为length
- 我们需要找到链表的尾结点
- 让尾结点连接头结点穿成环
- 计算出链表长度
- 找到目标链表断开的位置,即length-k的位置 说明:由于没有规定k是否小于length,所以我们要将k%length取模处理
题解代码
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} k
* @return {ListNode}
*/
var rotateRight = function(head, k) {
//说,要把大象装冰箱,拢共分几步?
//判断节点是否为空
if(!head) return null;
//找到链表的尾结点,穿成环
let cur = head,length = 1;
while(cur.next){
cur = cur.next;
length++;
}//找到尾结点,并计算链表的长度
cur.next = head;//尾结点指向head穿成环
//获取到链表的长度,找到length-k的位置,断开链表
//k%length是为了防止k>length的情况
for(let i = 0; i< length - k % length - 1; i++){
head = head.next;
}
cur = head.next;//让断开位置的下一个节点成为新的头结点
head.next = null;//断开链表
return cur;
};