1. 题目描述
给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。
示例 1:
输入: 1->2->3->4->5->NULL, k = 2
输出: 4->5->1->2->3->NULL
解释:
向右旋转 1 步: 5->1->2->3->4->NULL
向右旋转 2 步: 4->5->1->2->3->NULL
示例 2:
输入: 0->1->2->NULL, k = 4
输出: 2->0->1->NULL
解释:
向右旋转 1 步: 2->0->1->NULL
向右旋转 2 步: 1->2->0->NULL
向右旋转 3 步: 0->1->2->NULL
向右旋转 4 步: 2->0->1->NULL
2. 解题思路
对于这道题目,一个很直接的思路就是将单链表转化为一个环形链表,然后移动完成之后再将链表断开为单链表,实现步骤主要是三步:
- 首先遍历链表,找到链表的尾结点,将尾结点和头结点连起来,这样就形成了一个环形链表;
- 题目说的右移k步,这里我们让尾结点左移,相当于往左移动length-k步;
- 最后,移动完成之后,找到链表的尾结点,将环形链表断开为-单向链表。
复杂度分析:
- 时间复杂度:O(n),其中 n 是链表中的元素个数;
- 空间复杂度:O(1),因为只需要常数的空间。
3. 代码实现
/**
* 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 || !head.next){
return head
}
// 找到尾结点,将单链表形成环形链表
let tail = head
let length = 1
while(tail.next){
length++
tail = tail.next
}
tail.next = head
// 尾结点进行移动
k = k % length
for(let i = 0; i < length - k; i++){
tail = tail.next
}
// 找到头结点,断开环形链表
head = tail.next
tail.next = null
return head
};
4. 提交结果