61.旋转链表
题目描述
给定一个链表,旋转链表,将链表每个节点向右移动 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
示例 2:
输入: 0->1->2->NULL, k = 4
输出: 2->0->1->NULL
解释:
向右旋转 1 步: 2->0->1->NULL
向右旋转 2 步: 1->2->0->NULL
向右旋转 3 步: 0->1->2->NULL
向右旋转 4 步: 2->0->1->NULL
思路及算法
1.使用循环,设置临时变量来保存值然后移动。(不采取,假设链表长度很长,k很大,将有较大的开销)
2.将链表首尾相连变成环,找到合适的位置以后再断开。如下图:
我的代码
#include<iostream>
using namespace std;
struct ListNode {
int val;
ListNode* next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode* next) : val(x), next(next) {}
};
//尾插
ListNode* insert(ListNode* head, int x) {
ListNode* p = head;
while (p->next) {
p = p->next;
}
ListNode* t = new ListNode(x);
p->next = t;
return head;
}
//从头到尾打印链表
int pprint(ListNode* head) {
ListNode* p = head;
while (p) {
if (p->next)cout << p->val << "->";
else cout << p->val << endl;
p = p->next;
}
return 0;
}
//=============================================
//旋转链表
ListNode* rotateRight(ListNode* head, int k) {
if (nullptr == head || k < 0) {
return nullptr;
}
if (head->next == nullptr) {
return head;
}
ListNode* last = head;
int length = 1;
while (last->next)
{
last = last->next;
length++;
}
last->next = head;
int temp = length - k % length ;
while (temp--) {
last = last->next;
head = head->next;
}
last->next = nullptr;
return head;
}
//=========================================
int main() {
ListNode* head = new ListNode(1);
for (int i = 2; i < 6; i++) {
insert(head, i);
}
cout << "正向打印方法1:";
pprint(head);
cout << "旋转k次后的链表:";
ListNode* t=rotateRight(head, 2);
pprint(t);
return 0;
}