LeetCode61. 旋转链表


要将链表向右移动 k 次,可以将链表分为两部分:不移动部分和移动部分。
不移动部分就是链表前 size - k 个结点(size为链表结点个数),移动部分就是链表后 k 个结点。
对于移动部分的 k 个结点,需要将第一个结点置为新的 head 结点,并且移动部分的最后一个节点的 next 指针指向不移动部分的第一个结点。
而对于不移动部分,需要将最后一个结点的 next 指针指向NULL,因为这个结点是新链表的尾结点。
具体见代码:

class Solution {
public:
    ListNode* rotateRight(ListNode* head, int k) {
        if(head == NULL || k == 0) {            //特判,如果头节点为空或者无需移动
            return head;                        //直接返回原来的链表即可
        }
        ListNode* tail;                         //tail表示最后一个非空节点,也就是移动部分的最后一个节点
        int size = 0;                           //size表示链表非空节点的个数,k需要对size取余
        for(ListNode* p = head; p != NULL; p = p -> next) {
            tail = p;                           //找到尾节点
            ++size;                             //并计算链表大小
        }
        k = k % size;                           //k需要对size取余,因为每移动size次就等于没移动
        if(k == 0) {                            //如果k为0,就无需移动
            return head;
        }
        ListNode* first = head;                  //first表示移动部分的最后一个节点
        for(int i = 0; i < size - k - 1; ++i) {  //因为移动部分有 n - k 个节点,所以从head往后 n - k - 1 次就找到了移动部分的最后一个节点first
            first = first -> next;
        }
        tail -> next = head;                     //移动部分放到了不移动部分的前面,所以移动部分的尾节点的next指针指向移动部分的第一个节点head
        head = first -> next;                    //此时不移动部分的最后一个节点first的next指针指向移动部分的第一个节点,而移动部分的第一个节点就是新链表的头节点,所以更新一下
        first -> next = NULL;                    //因为first是新链表的尾结点,所以first的next指针指向NULL
        return head;
    }
};
posted @ 2020-06-27 22:07  machine_gun_lin  阅读(82)  评论(0编辑  收藏  举报