题目
Given a list, rotate the list to the right by k places, where k is non-negative.
For example:
Given 1->2->3->4->5->NULL and k = 2,
return 4->5->1->2->3->NULL.
题目大意:将链表的后k个节点放在链表的头部。
思路
思路比较简单,就是,找到链表的倒数第k个节点的位置作为新链表的头指针,将最后一个节点的next指向原来的头结点即可。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* rotateRight(struct ListNode* head, int k) {
if(head==NULL){
return NULL;
}
struct ListNode *node=head;
//先求链表的长度
int len=0;
while(node!=NULL){
node=node->next;
len++;
}
// if(k>len){
// return NULL;
// }
// else if(k==len){//特殊情况
// return head;
// }
k=k%len;
if(k==0){
return head;
}
//先找到倒数第k个节点的位置
struct ListNode *pre=NULL;
struct ListNode* cur=head;
int len1=len-k;
while(len1>0){
pre=cur;
cur=cur->next;
len1--;
}
pre->next=NULL;
struct ListNode *newHead=cur;//保存新的节点
while(cur!=NULL){
pre=cur;
cur=cur->next;
}
pre->next=head;
return newHead;
}
遇到的问题
1、没有考虑到k=0这种情况。
解决方法:加上如下代码即可
if(k==0){
return head;
}
2、但是题目中并没有描述当k>len时该返回什么,刚开始我考虑的是当k>len时,就返回NULL。因此出现了如下的报错。
有了以上的报错,我就以为当k>len时应该返回原链表的头结点。因此就添加了这样的代码,如下:
if(k>=len){
return head;
}
3、对第二个问题进行改进之后,就出现了如下的问题:
这时候我才明白,原来要这样来考虑:k=k%len;即对求余之后的k进行操作。
但是,你要我这么做,你题干上面至少要把这要求说清楚吧,妈蛋
最后AC的结果如下:
从结果可以看出,虽然AC了,但是,效率并不太高。因此,还需要改进。
把上面的代码精简了一下,使思路更加清晰,如下所示:
分两步:
- 第一步:先求链表的长度,并保存尾结点的指针
- 第二步:找到倒数第k个节点的指针作为新链表的头指针
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* rotateRight(struct ListNode* head, int k) {
//改进
if(head==NULL){
return NULL;
}
struct ListNode *node=head;
struct ListNode *pre=NULL;//记录最后一个节点的指针
//第一步:先求链表的长度,并保存尾结点的指针
int len=0;
while(node!=NULL){
pre=node;
node=node->next;
len++;
}
k=k%len;
if(k==0){
return head;
}
//第二步:找到倒数第k个节点的指针作为新链表的头指针
struct ListNode *preNode=NULL;//用来指向新链表的尾结点
struct ListNode* cur=head;
int len1=len-k;
while(len1>0){
preNode=cur;
cur=cur->next;
len1--;
}
preNode->next=NULL;
pre->next=head;
return cur;
}
运行了下,在效率上并没有多大的变化。