链表的循环,切割问题
package Level3;
import Utility.ListNode;
/**
*
* Rotate List
*
* 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.
*
*/
public class S61 {
public static void main(String[] args) {
ListNode head = new ListNode(1);
ListNode n2 = new ListNode(2);
ListNode n3 = new ListNode(3);
ListNode n4 = new ListNode(4);
ListNode n5 = new ListNode(5);
head.next = n2;
n2.next = n3;
n3.next = n4;
n4.next = n5;
ListNode rotateHead = rotateRight(head, 2);
rotateHead.print();
}
public static ListNode rotateRight(ListNode head, int n) {
if(head == null){
return null;
}
ListNode back = head;
ListNode front = head;
ListNode end = head;
// 先把链表改为循环链表
while(front.next != null){
front = front.next;
}
end = front; // 记录原尾节点
front.next = head; // 形成环
front = head; // 复原front指针
// 使得front在back前面n个距离
for(int i=0; i<n; i++){
front = front.next;
}
// 双指针同步移动
while(front != end){
front = front.next;
back = back.next;
}
ListNode rotateHead = back.next; // 找到rotate之后的链表头
back.next = null; // 切开循环链表
return rotateHead;
}
}
要点就是先把单链表变成循环链表
/**
* 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) {
return null;
}
ListNode cur = head;
while(cur.next != null) {
cur = cur.next;
}
cur.next = head;
ListNode fast = head, slow = head;
for(int i=0; i<n; i++) {
fast = fast.next;
}
while(fast.next != head){
fast = fast.next;
slow = slow.next;
}
ListNode newHead = slow.next;
slow.next = null;
return newHead;
}
}