原题
感觉这题没有交代清楚细节,解释一下。本题是将最后K个节点移动到头部,其中k如果大于链表的长度的话,k要根据链表的长度取余再做变化。例如,示例中链表长度为5,那么当k=7的时候,K = K %5 = 2,返回4->5->1->2->3->NULL
解法概要
该题共有2种解法
Ⅰ、快慢指针
Ⅱ、将原链表变为循环链表(参考别人解法),更加简单
解法1:快慢指针
解题思路
使fast指针领先slow指针k个节点,当fast指针到达尾部的时候,slow指针指向的正好是需要变更链接关系的节点。
图解
代码
public class Solution61 {
public ListNode rotateRight(ListNode head, int k) {
if(head == null || head.next == null || k <= 0)
return head;
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode slow = dummy , fast = dummy, iterator = head;
int length = getListLength(head);
//初始化fast的位置
for (int i = 0; i < k % length; i++){
fast = fast.next;
}
//移动slow与fast
while (fast != null && fast.next != null){
slow = slow.next;
fast = fast.next;
}
fast.next = dummy.next;
dummy.next = slow.next;
slow.next = null;
return dummy.next;
}
private int getListLength(ListNode head) {
int count = 0;
ListNode iterator = head;
while (iterator != null){
iterator = iterator.next;
count++;
}
return count;
}
}
解法2:循环链表
参考
解法2-循环链表
解题思路
将链表连接成环,tail前进对应的步数,在对应的位置重新将链表断开。
代码
class Solution {
public:
ListNode* rotateRight(ListNode* head, int k) {
if(!head) return head;
int len=1; // number of nodes
ListNode *newH, *tail;
newH=tail=head;
while(tail->next) // get the number of nodes in the list
{
tail = tail->next;
len++;
}
tail->next = head; // circle the link
if(k %= len)
{
for(auto i=0; i<len-k; i++) tail = tail->next; // the tail node is the (len-k)-th node (1st node is head)
}
newH = tail->next;
tail->next = NULL;
return newH;
}
};