LeetCode Day49 rotate-list

我的方法:一次一次做,共做k%n次旋转:

class Solution {
public:
    ListNode* rotateRight(ListNode* head, int k) {
        if(head==NULL||head->next==NULL) return head;
        int n = 0;
        ListNode *cur = head;
        while (cur) {++n;cur = cur->next;}//计算链表长度
        k %= n;
        while(k){
            ListNode *p=head,*q=head->next;
            while(q->next!=NULL){
                p=p->next;
                q=q->next;
            }
            p->next=NULL;
            q->next=head;
            head=q;
            k--;
        }
        return head;
    }
};

快慢指针:快指针先走k%n步,两个再一起走,直到快指针到尾部,将头尾连起来,慢指针的下一个位置作为新的头,慢指针所在位置指向尾部

class Solution {
public:
    ListNode* rotateRight(ListNode* head, int k) {
        if(head==NULL||head->next==NULL) return head;
        int n = 0;
        ListNode *cur = head;
        while (cur) {++n;cur = cur->next;}
        k %= n;
        ListNode *fast=head,*slow=head;
        for(int i=0;i<k;i++) fast=fast->next;
        if(!fast) return head;
        while(fast->next){
            fast=fast->next;
            slow=slow->next;
        }
        fast->next=head;
        head=slow->next;
        slow->next=NULL;
        return head;
    }
};

从上代码分析来看,不需要两个指针,快指针只负责把首尾连起来.慢指针才是确定位置的关键,儿使用两个指针只是为了找到倒数第k个位置,在已知长度n的条件下,我们直接找n-k就可以.只要找到慢指针的位置,在慢指针处将首尾连起来的环断开就可以.原理是先遍历整个链表获得链表长度n,然后此时把链表头和尾链接起来,在往后走n - k % n个节点就到达新链表的头结点前一个点,这时断开链表即可,代码如下:

class Solution {
public:
    ListNode* rotateRight(ListNode* head, int k) {
        if(head==NULL||head->next==NULL) return head;
        int n = 1;
        ListNode *cur = head;
        while (cur->next) {++n;cur = cur->next;}
        cur->next=head;
        for(int i=0;i<n-k%n;i++){
            cur=cur->next;
        }
        head=cur->next;
        cur->next=NULL;
        return head;
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_41394379/article/details/84852930
今日推荐