思路:
①先计算出head链表的长度
②通过观察,发现题目的意思是从链表的末尾依次取出元素放置链表头部,那么这一定是个循环(参见示例2),所以在k>len的时候可以将k - n*len,那么新的k如果和len相等,那就刚好凑成一个循环,直接返回head即可,否则进入循环,找到第len-k个元素(头节点为1)设为p
③temp = p->next,q = p->next,对q进行循环,如果q->next = NULL,那么就让q->next = head
完成上述三步,刚好凑成一个新的链表,链表头部为temp返回即可
#include<iostream>
#include<cstdlib>
using namespace std;
typedef struct ListNode
{
int val;
ListNode *next;
} ListNode,*PtrToNode;
void Print(PtrToNode N)
{
PtrToNode p = N;
while(p!=NULL)
{
cout<<p->val<<" ";
p = p->next;
}
}
PtrToNode Insert(int val,PtrToNode N)
{
PtrToNode p = (PtrToNode)malloc(sizeof(ListNode));
p->val = val;
p->next = NULL;
if(N==NULL)
{
N = p;
}
else
{
PtrToNode q = N;
while(q->next != NULL)
{
q = q->next;
}
q->next = p;
}
return N;
}
class Solution
{
public:
ListNode* rotateRight(ListNode* head, int k)
{
if(k!=0 && head!=NULL)
{
int len = 0;
ListNode *p = head,*q,*temp = NULL;
while(p!=NULL)
{
len++;
p = p->next;
}
while(k>len)
k-=len;
if(k==len)
return head;
p = head;
len-=k;
while(len>1)
{
p = p->next;
len--;
}
q = p;
temp=p->next;
while(q->next!=NULL)
q=q->next;
q->next = head;
p->next = NULL;
return temp;
}
return head;
}
};
int main()
{
Solution s;
PtrToNode N,M;
N = NULL;
N = Insert(1,N);
N = Insert(2,N);
N = Insert(3,N);
N = Insert(4,N);
N = Insert(5,N);
Print(N);
cout<<endl;
N = s.rotateRight(N,2);
cout<<endl;
Print(N);
return 0;
}
进化版:(膜大佬)
直接把链表转为一个环形链表,顺便计算出链表长度len,如果k超过len,则k对len取模 k%ken,然后进行len-k%len次循环,将p->next指向新的头节点,这个时候head = p->next,p->next = NULL,一条新的链表出来了
class Solution
{
public:
ListNode* rotateRight(ListNode* head, int k)
{
if(head==NULL || head->next==NULL)
return head;
ListNode *rear = head, *p = head;
int len = 1;
// for(; rear->next; len++)
// rear = rear->next;
while(rear->next!=NULL && len++)
rear = rear->next;
rear->next = head;
for(int i=1; i<len-k%len ; i++)
{
p = p->next;
}
head = p->next;
p->next = NULL;
return head;
}
};