Given a list, rotate the list to the right by k places, where k is non-negative.
For example:
Given 1->2->3->4->5->NULL
and k = 2
,
return 4->5->1->2->3->NULL
.
Solution:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode rotateRight(ListNode head, int n) {
if(head==null||head.next==null || n==0) return head;
ListNode fakeHead = new ListNode(0);
fakeHead.next=head;
int length=0;
ListNode start=fakeHead, end=fakeHead;
for(int i=0; i<n; i++){
if(end.next==null) break;
end=end.next;
length++;
}
if(end.next==null){
//when n>=length
//int startPos = (length-n)%length+length; //Or:
int startPos=n%length;
if(startPos==0) return fakeHead.next;
startPos=length-startPos;
for(int i=0; i<startPos; i++){
start=start.next;
}
}
else{
while(end.next!=null){
start=start.next;
end=end.next;
}
}
//reorder list
end.next=fakeHead.next;
fakeHead.next=start.next;
start.next=null;
return fakeHead.next;
}
}
Note:如果end后移n次后end.next还不是null,说明list的长度>n。则将start和end整体后移。
否则,说明list的长度<=n,这时候需要找到rotate的实际次数。对于一个长为length的list,若rotate的次数为length,则结果为原list。所以rotate的实际次数是n%length,若结果为0,则直接返回原list;否则,需要找到相应的start点,即修改list的起始点。
注意代码中
int startPos = (length-n)%length+length;
其实和
int startPos=n%length;
startPos=length-startPos;
一个效果(startPos不为0时)。但是后者比较好理解。
另外一个负数对一个正数取模,计算如下:
result=m%n, where m<=0, n>0
Assume m=xn+result, where x<=0, result<0 and -result<n.
比如(-5)%3。 -5=3*(-1)+(-2)。所以(-5)%3=-2。