旋转链表-[LeetCode-61]

131 阅读1分钟

题目描述

思路分析

以以下的例子为例:

输入: 1->2->3->4->5->NULL, k = 2
输出: 4->5->1->2->3->NULL
解释:
向右旋转 1 步: 5->1->2->3->4->NULL
向右旋转 2 步: 4->5->1->2->3->NULL
长度为5,右移2,则 2 % 5 = 2,头结点向右移(5 - 2) = 3 次,即为新的头结点,也就是4,那么4前面的3必为最后的节点。
则其next需要置为null。同时原始链表的最后一个节点需要指向原始的头结点,保证链起来,即可。

代码实现

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* rotateRight(ListNode* head, int k) {
        if (!head || !head->next || k == 0) {
            return head;
        }

        // 遍历链表得到长度
        int len = 0;
        ListNode* tmp = head;
        while(tmp) {
            len++;
            tmp = tmp->next;
        }

        k = k % len;
        if (k == 0) {
            return head;
        }

        int forward_len = len - k; // 前进步数
        int i = 0;
        ListNode* new_head = head;
        while(i < forward_len - 1) {
            // 得到新的头结点的前一个节点,因为需要将该节点的next置为null
            new_head = new_head->next;
            i++;
        }
        ListNode* ret = new_head->next;
        new_head->next = NULL; // 该节点变为最后的节点
        
        // 遍历到最后一个节点,将该节点指向最初的头结点
        ListNode* cur_node = ret;
        while(cur_node->next) {
            cur_node = cur_node->next;
        }
        cur_node->next = head;
        
        return ret;
    }
};