Rotate List

来源:互联网 发布:js获取单选框选中属性 编辑:程序博客网 时间:2024/05/18 02:34
 

题目:输入k和链表的头结点,循环右移链表的后K个结点。


For example:
Given1->2->3->4->5->NULLand  k  =2,
return4->5->1->2->3->NULL.


思路:

1.首先要找链表的倒数第K个结点;

2.因循环右移的K个结点仍是按原来顺序排列,可考虑用一个先进先出的容器 即队列 将 后K个结点

存储,依次连接在链表首处;

3.但此解法空间复杂度为O(k);

4.将链表首尾相接成环,然后在第K个结点前的结点处断开即可;


因leetcode上测试用例中的k有大于length of list 的情况,故要先遍历一遍然后使k=k%(length of list),

时间复杂度仍为O(n).


还有一个方法,其他博客也有:

用快慢指针来解,快指针先走k步,然后两个指针一起走,当快指针走到末尾时,慢指针的下一个位置是新的顺序的头结点,这样就可以旋转链表了,自信满满的写完程序,放到OJ上跑,以为能一次通过,结果跪在了各种特殊情况,首先一个就是当原链表为空时,直接返回NULL,还有就是当k大于链表长度和k远远大于链表长度时该如何处理,我们需要首先遍历一遍原链表得到链表长度n,然后k对n取余,这样k肯定小于n,就可以用上面的算法了,代码如下:


class Solution {
public:
    ListNode* rotateRight(ListNode* head, int k) {
       if(!head)return NULL;//特殊情况,链表为空
       int size =0;
       ListNode *cur = head;
       while(cur){
           cur = cur->next;
           size++;
       }

       k = k%size;


       ListNode *fast = head;
       ListNode *slow = head;
       for(int i=0;i<k;i++){
           fast = fast->next;
       }
       

       if(!fast) return head; //特殊情况,k的位置正好在链表末尾


       while(fast->next){  //快慢指针同时滑动,直到快指针到末尾
           fast = fast->next;
           slow = slow->next;
       }
       
        fast->next=head; //环形链表
        head = slow->next;//找到表头
        slow->next = NULL;//断开链表
        return head;
       
    }
};


方法不难,用笔演算一下步骤就知道了思路

0 0
原创粉丝点击