题目描述:
给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。
示例1:
输入: 1->2->3->4->5->NULL, k = 2
输出: 4->5->1->2->3->NULL
解释:
向右旋转 1 步: 5->1->2->3->4->NULL
向右旋转 2 步: 4->5->1->2->3->NULL
链接:https://leetcode-cn.com/problems/rotate-list
1.思路1
思路分析:和普通数组旋转一样,先进行取模去重,再整体逆置,局部逆置,即可对链表进行反转。
例:
代码:
class Solution {
public:
int LenghtOfList(ListNode* head)//求长度
{
int count = 0 ;
while(head != nullptr)
{
head = head->next;
++count;
}
return count;
}
ListNode* ListReverse(ListNode* head)//链表逆置
{
if(head == nullptr || head->next == nullptr)
return head;
ListNode* p = head;
ListNode* q = p->next;
p->next = nullptr;
while(q != nullptr)
{
p = q;
q = q->next;
p->next = head;
head = p;
}
return head;
}
ListNode* rotateRight(ListNode* head, int k) {
if(head == nullptr || head->next == nullptr || k == 0)
return head;
int length = LenghtOfList(head);
k %= length;//去重
if(k == 0)//为0,直接返回
return head;
head = ListReverse(head);//整体逆置
ListNode* p = head;
while(--k)
p = p->next;
ListNode* q = p->next;
p->next = nullptr;//断开链表
head = ListReverse(head);//局部逆置
q = ListReverse(q);//局部逆置
p = head;
while(p != nullptr)
{
if(p->next == nullptr)
{
p->next = q;//链表链接起来
break;
}
p = p->next;
}
return head;//返回链表
}
};
2.思路2
上述方法并没有考虑到链表的结构,且逆置太多,只需要找到链表的要旋转的节点,将前节点置空,再将链表后续链表,链接到头部即可。
- 首先还是去重(一定需要这步操作)
- 通过长度减去旋转次数,找到在哪一个节点旋转,该节点就作为返回的头节点
- 后面节点直接链接到头节点
例:
代码:
class Solution {
public:
int LenghtOfList(ListNode* head)//求链表长度
{
int count = 0 ;
while(head != nullptr)
{
head = head->next;
++count;
}
return count;
}
ListNode* rotateRight(ListNode* head, int k) {
if(head == nullptr || head->next == nullptr || k == 0)
return head;
int length = LenghtOfList(head);
k %= length;//去重
if(k == 0)//等于0,直接返回
return head;
k = length - k;//找到断开的节点
ListNode* p = head;
while(--k)
p = p->next;
ListNode* q = p->next;//该节点就是返回的起始节点
p->next = nullptr;
p = q;
while(q != nullptr)
{
if(q->next == nullptr)
{
q->next = head;//链接起来
break;
}
q = q->next;
}
return p;//直接返回p
}
};