1.问题描述
给定一个链表,旋转链表,将链表每个节点向右移动 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
2.输入说明
3.输出说明
4.范例
输入:
输出:
5.思路
代码中创建的链表是无头结点单链表,其中k为旋转的步数,返回旋转后的链表头指针。
使用c++STL的map对原链表进行映射,并使用vector函数构造新的链表。
设置 n为链表的长度,即链表的结点数,i为map映射的标记,设置为0。其中需要先将链表设置为循环链表,当k=0时,选择vector[n-k%n]作为第一个结点,依次显示,显示到最后一个结点时,再将next设置为NULL,即可成为一个旋转后的单链表。
6.代码
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<map>
#include<vector>
using namespace std;
struct ListNode
{
int val;
ListNode *next;
ListNode() : val(0), next(NULL) {}
ListNode(int x) : val(x), next(NULL) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
class Solution {
public:
ListNode* rotateRight(ListNode* head, int k)
{
std::vector<ListNode *>node_vec;
std::map<ListNode *,int>node_map;
int i=0;
ListNode *p=head;
if(p==NULL||k==0)
return head;
while(p)
{
node_vec.push_back(new ListNode(p->val));//首先将创建的vector新链表
node_map[p]=i;//对原链表进行映射
p=p->next;
i++;
}
int n=i;
i=0;
while(i<n-1)
{
node_vec[i]->next=node_vec[i+1]; //对vector创建的新链表进行按原顺序连接
i++;
}
node_vec[i]->next=node_vec[0]; //将最后一个结点的next设置为第一个结点,形成一个循环链表
n=n-k%n;//根据旋转k的步数推算出第一个结点的映射规律
if(n==i+1)
{
return head;//当n等于自己时,旋转的k个步长和原链表一样,因此不需要进行修改
}
head=node_vec[n]; //将第n=n-k%n个结点赋值给head
node_vec[n-1]->next=NULL;//第n个结点设置为头结点,为了把循环链表变为单链表,需要将第n-1个结点设置为空,即可设置为单链表
return head;
}
};
ListNode *createByTail()
{
ListNode *head;
ListNode *p1,*p2;
int n=0,num;
int len;
cin>>len;
head=NULL;
while(n<len && cin>>num)
{
p1=new ListNode(num);
n=n+1;
if(n==1)
head=p1;
else
p2->next=p1;
p2=p1;
}
return head;
}
void displayLink(ListNode *head)
{
ListNode *p;
p=head;
cout<<"head-->";
while(p!= NULL)
{
cout<<p->val<<"-->";
p=p->next;
}
cout<<"tail\n";
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int k;
ListNode* head = createByTail();
cin>>k;
head=Solution().rotateRight(head,k);
displayLink(head);
return 0;
}