题意:
        给定链表的头节点,旋转链表,将链表每个节点往右移动 k 个位置,原链表后 k 个位置的节点则依次移动到链表头。
        即,例如链表 : 1->2->3->4->5 k=2 则返回链表 4->5->1->2->3。

方法一:
模拟

思路:
        直接模拟。
        根据题意的k值,用链表长度n - k-1,得到向右遍历的步数,可到达左部分链表的尾结点,标记为尾结点(即尾结点->next=null);
        再将右部分链表的尾结点指向左部分链表的头结点。
        
        

class Solution {
public:
    
    ListNode* rotateLinkedList(ListNode* head, int k) {
        if(head==nullptr)
            return head;
        ListNode *p=head;
        int n=0;
        while(p){//计算链表长度
            n++;
            p=p->next;
        }
        k%=n;//取余运算
        if(k==0)
            return head;
        int cnt=n-k-1;//向右遍历的长度-1
        
        p=head;
        while(cnt--){
            p=p->next;
        }
        ListNode *q=p->next;//新的首节点
        p->next=nullptr;//尾结点结束标记
        
        ListNode *t=q;
        p=q->next;
        while(p){
            t=p;
            p=p->next;
        }
        t->next=head;//拼接链表
        return q;
    }
};

时间复杂度:
空间复杂度:

方法二:
辅助数组

思路:
        利用辅助数组存储链表旋转后的新序列,再遍历链表将新值覆盖旧值即可。

class Solution {
public:
    
    ListNode* rotateLinkedList(ListNode* head, int k) {
        if(head==nullptr)
            return head;
        ListNode *p=head;
        int n=0;
        while(p){//计算链表长度
            n++;
            p=p->next;
        }
        k%=n;//取余运算
        if(k==0)
            return head;
        int cnt=n-k;
        p=head;
        for(int i=0;i<cnt;i++){
            p=p->next;
        }
        vector<int> v;//辅助数组
        while(p){
            v.push_back(p->val);
            p=p->next;
        }
        p=head;
        for(int i=0;i<cnt;i++){
            v.push_back(p->val);
            p=p->next;
        }
        p=head;
        for(int i=0;i<n;i++){//新值覆盖旧值
            p->val=v[i];
            p=p->next;
        }
        return head;
    }
};

时间复杂度:
空间复杂度: