【小白爬Leetcode61】1.13 旋转链表 Rotate List


Leetcode 61 m e d i u m \color{#FF7D00}{medium} medium

点击进入原题链接:LeetCode中国站

题目

Description

Given a linked list, rotate the list to the right by k places, where k is non-negative.

Example1:

Input: 1->2->3->4->5->NULL, k = 2
Output: 4->5->1->2->3->NULL
Explanation:
rotate 1 steps to the right: 5->1->2->3->4->NULL
rotate 2 steps to the right: 4->5->1->2->3->NULL

Example2:

Input: 0->1->2->NULL, k = 4
Output: 2->0->1->NULL
Explanation:
rotate 1 steps to the right: 2->0->1->NULL
rotate 2 steps to the right: 1->2->0->NULL
rotate 3 steps to the right: 0->1->2->NULL
rotate 4 steps to the right: 2->0->1->NULL

中文描述

给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。

示例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

示例2

输入: 0->1->2->NULL, k = 4
输出: 2->0->1->NULL
解释:
向右旋转 1 步: 2->0->1->NULL
向右旋转 2 步: 1->2->0->NULL
向右旋转 3 步: 0->1->2->NULL
向右旋转 4 步: 2->0->1->NULL

思路: 先遍历一遍链表,连成环,再用顺时针代替逆时针

思路很简单:

  1. 第一遍遍历先把链表连成环(最后一个节点连到第一个节点上)。

  2. first 指针指向要return的节点的前一个节点。那么环的顺时针运动实际上就是指针 first 从head开始的逆时针运动。(时针的顺时针转动,恰如表盘的逆时针运动)

  3. 而众所周知,一个长为M的跑道,逆时针跑N,和逆时针跑N%M是一样的,和顺时针跑(M-(N%M))也是一样的。因此,我只需要让first 指针从原表头出发,顺着链表方向再走length-(k%length)步就可以了。
    例如:
    令M=400m,N=500m,那么:一个400m的跑道,逆时针跑100m,和逆时针跑(500%400)= 100m 是一样的,和顺时针跑(400-(500%400))= 300m 是一样的。

  4. 但是first走了length-(k%length)步之后,需要将first的上一个节点的->next指向NULL,来打破原来的环,这样就需要一个额外的pre指针来记录first的上一个节点。为了避免这种麻烦,让first少走一步,走length-(k%length)-1步,令res = 循环后的first->next即可

  5. 最后return res

源代码如下:

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

在这里插入图片描述
复杂度分析

时间复杂度:O(N)
空间复杂度:O(1),因为只用到几个指针,只需要常数的空间

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值