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
.
题目:倒着数k个node,从那开始到结尾和之前那部分对调,那个例子就是,4->5拿前面来,1->2->3拿后面去。
思路:我自己是用了三个指针,分别是移到k位置,第一位,然后把三段拼起来。思路是正确,但是太复杂,绕来绕去,后面提交也是超时了。
public ListNode rotateRight(ListNode head, int k) {
ListNode result = new ListNode(-1);
result.next = head;
ListNode first = result;
ListNode second = head;
ListNode third = result;
if(head == null) {
return result.next;
}
if(head.next == null){
return head;
}
int len = 1;
while(result.next != null) {
len++;
result = result.next;
}
int i = 0;
while(i < len-k) {
i++;
first = first.next;
}
third.next = first;
int j = 1;
while(j < len-1-k) {
second = second.next;
j++;
}
second.next = null;
ListNode flag = third;
while(flag.next != null) {
flag = flag.next;
}
flag.next = head;
return third.next;
}
下面是参考网友的思路,用两个指针, faster/slower,先对faster设步长为n,然后faster和slower再一起走,知道faster.next==null,说明slower指向要倒着数的开始点的前一个位置。
public ListNode rotateRight(ListNode head, int n) {
if(head==null||head.next==null||n==0)
return head;
ListNode fast = head, slow = head,countlen = head;
ListNode newhead = new ListNode(-1);
int len = 0;
while(countlen!=null){
len++;
countlen = countlen.next;
}
n = n%len;
if(n==0)
return head;
for(int i = 0; i < n; i++)
fast = fast.next;
while(fast.next!=null){
slow = slow.next;
fast = fast.next;
}
newhead = slow.next;
fast.next = head;
slow.next = null;
return newhead;
}
还有一种更简单的思路,把整个链表连成一个环,在重新分割就可以了。
public ListNode rotateRight(ListNode head, int n) {
if (head == null || n == 0)
return head;
ListNode p = head;
int len = 1;//since p is already point to head
while (p.next != null) {
len++;
p = p.next;
}
p.next = head; //form a loop
n = n % len;
for (int i = 0; i < len - n; i++) {
p = p.next;
} //now p points to the prev of the new head
head = p.next;
p.next = null;
return head;
}