Given a linked list, rotate the list to the right by k places
where k is non-negative.
给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。
Example 1:
Input: 1->2->3->4->5->NULL, k = 2
Output: 4->5->1->2->3->NULL
Explanation:
rotate 1 steps to the right: 5->1->2->3->4->NULL
rotate 2 steps to the right: 4->5->1->2->3->NULL
Example 2:
Input: 0->1->2->NULL, k = 4
Output: 2->0->1->NULL
Explanation:
rotate 1 steps to the right: 2->0->1->NULL
rotate 2 steps to the right: 1->2->0->NULL
rotate 3 steps to the right: 0->1->2->NULL
rotate 4 steps to the right: 2->0->1->NULL
- 双指针找位置+简单指针变化(注意k有可能大于链的长度)
- 找到倒数k-1的位置(slow)fast先走k步(用具体的数来k)
- 断链 、连接
解题思路
这道题的最重要的一个思路是找最后一个节点的前第k个节点!
那么我们要判断链表长度len和k的关系:
① k%len==0
这种情况直接返回head就好,因为旋转后是一样的。
② k>len
这样就要取新的k=k%len
③ k<len
以上三种情况都是为了k要小于len
然后我们找最后一个节点的前第k个节点
定义一个dummynode节点,dummynode->next=head.实际上这个dummynode是为了方便操作
而创建,为了方便对真正的头节点进行操作
定义一个fast和slow,fast是较前的一个节点,slow是较后的节点
fast先往前走k次,然后fast和slow一起走,直到fast是最后一个节点(fast->next==NULL)
12345->45123(k=2)//调整前最终fast指向5,slow指向3,分别指向两段链表的最后一个节点
后面就简单了,就是指来指去的问题了
首先,fast->next=head;//5指向1
然后,start->next=tmpRear->next;//头节点为4(slow->next)
最后,tmpRear->next=NULL;//确定尾指针
要做三件事
1确定头节点
2确定连接的位置,改动指针,连接
3确定尾节点指向空
快慢指针的原理:目标找到两段链表的尾节点,在加一个dummynode两段链表的头节点也能表示出来了。
如何找到尾节点:第二段链表表尾就是整段链表尾端。因为要移动k个位置,所以链表后k个元素一定属于第二段链表,因此倒数k+1个元素为第一段链表尾端,现在就演变成了找到倒数第k+1个节点,fast先走k步就好了
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode rotateRight(ListNode head, int k) {
int len=getlen(head);
if(head==null||k%len==0||head.next==null){
return head;
}
//找到倒数k+1的位置(slow)fast先走k步、断链 、重新接起来
ListNode slow=head;
ListNode fast=head;
k=k%len;
for(int i=0;i<k;i++){//fast!=null
if(fast==null){
return head;
}
fast=fast.next;
}
//fast.next!=null 因此上边的for循环是k
// 为什么(fast.next!=null,因为需要得到的是fast是最后一个节点——非空—断链的时候要用)
while(fast.next!=null){
fast=fast.next;
slow=slow.next;
}
ListNode newhead=slow.next;
fast.next=head;
slow.next=null;
return newhead;
}
int getlen(ListNode head){
int len=0;
while(head!=null){
head=head.next;
len++;
}
return len;
}
}