1.题目
旋转链表:给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置
2.思路
- 如果链表为空(
head==null
)或者链表只有头结点(head.next==null
)或者向右移动次数k=0
,那么都是原链表,直接返回head
- 遍历链表求出链表长度
len
,注意到当向右移动的次数k ≥ len
时,我们仅需要向右移动k % len
次即可。因为每len
次移动都会让链表变为原状。这样我们可以知道,新链表的最后一个节点为原链表的第len - k % len
个节点;如果k
是链表长度len
的倍数,直接返回原链表的head
。 - 如果
k
不是链表长度len
的倍数,现将尾结点的next
指向头结点head
,构建环,然后将尾结点cur
(因为之前遍历链表求长度cur
指向了尾结点)走count = len - k % len
步,此时cur.next
就是新链表的头结点,然后cur
就是新链表的尾结点,所以将cur.next
置空。
3. 代码
//61. 旋转链表
//给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。
public ListNode rotateRight(int k) {
if (head == null || head.next == null || k == 0) {
return head;
}
int len = 1;//链表长度
ListNode cur = head;
while (cur.next != null) {
len++;
cur = cur.next;
}
int count = len - k % len;
if (count == len) {
return head;
}
cur.next = head;//构建环
while (count > 0) {
cur = cur.next;
count--;
}
ListNode newHead = cur.next;//新链表的头结点
cur.next = null;//新链表尾结点置空
return newHead;
}
测试:
public static void main(String[] args) {
MyLinkedList myLinkedList = new MyLinkedList();
myLinkedList.addLast(1);
myLinkedList.addLast(2);
myLinkedList.addLast(3);
myLinkedList.addLast(4);
myLinkedList.addLast(5);
myLinkedList.display();
System.out.println("================");
ListNode ret = myLinkedList.rotateRight(7);
myLinkedList.display(ret);
}