题意:
给定链表的头节点,旋转链表,将链表每个节点往右移动 k 个位置,原链表后 k 个位置的节点则依次移动到链表头。
即,例如链表 : 1->2->3->4->5 k=2 则返回链表 4->5->1->2->3。
方法一:
模拟
思路:直接模拟。
根据题意的k值,用链表长度n - k-1,得到向右遍历的步数,可到达左部分链表的尾结点,标记为尾结点(即尾结点->next=null);
再将右部分链表的尾结点指向左部分链表的头结点。
class Solution {
public:
ListNode* rotateLinkedList(ListNode* head, int k) {
if(head==nullptr)
return head;
ListNode *p=head;
int n=0;
while(p){//计算链表长度
n++;
p=p->next;
}
k%=n;//取余运算
if(k==0)
return head;
int cnt=n-k-1;//向右遍历的长度-1
p=head;
while(cnt--){
p=p->next;
}
ListNode *q=p->next;//新的首节点
p->next=nullptr;//尾结点结束标记
ListNode *t=q;
p=q->next;
while(p){
t=p;
p=p->next;
}
t->next=head;//拼接链表
return q;
}
};
时间复杂度:
空间复杂度:![]()
方法二:
辅助数组
思路:利用辅助数组存储链表旋转后的新序列,再遍历链表将新值覆盖旧值即可。
class Solution {
public:
ListNode* rotateLinkedList(ListNode* head, int k) {
if(head==nullptr)
return head;
ListNode *p=head;
int n=0;
while(p){//计算链表长度
n++;
p=p->next;
}
k%=n;//取余运算
if(k==0)
return head;
int cnt=n-k;
p=head;
for(int i=0;i<cnt;i++){
p=p->next;
}
vector<int> v;//辅助数组
while(p){
v.push_back(p->val);
p=p->next;
}
p=head;
for(int i=0;i<cnt;i++){
v.push_back(p->val);
p=p->next;
}
p=head;
for(int i=0;i<n;i++){//新值覆盖旧值
p->val=v[i];
p=p->next;
}
return head;
}
};
时间复杂度:
空间复杂度:![]()



京公网安备 11010502036488号