leetcode 61. Rotate List(旋转链表)only rotate once

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

Example 1:

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
Example 2:

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

这道题是将链表右shift,尾部的移到head前面,shift k次

因为是单向链表,只有head指针,而没有tail,所以要找到最右边的元素,必须从head一直走到最后的null前面一个元素,复杂度O(N),shift k次就需要访问最右边的元素k次,有没有更简便一些的方法,当然有。

观察第一个例子,链表长度5,shift k=2次,就是把最后两个元素移到前面对不对
再看第二个例子,链表长度3,shift k=4次,转来转去,当转到k=3的时候发现没有,链表又回到初始的模样,第四次相当于最后一个元素移到前面,等于说前3次,也就是链表长度次移动是无用功的。我们只需要移动最后k%length 个元素(length指链表长度)。

要移动最后k%length个元素,需要知道length吧,需要知道tail指针(指向最后一个元素的指针),还需要知道从右边数k%length个元素的前一个元素的指针。

所以我们定义两个指针,一个faster,一个slower,让faster先走,走到最后一个元素,这个时候也就知道了length,一石二鸟。
然后根据length计算出k%length, 让slower走到(length-k%length)的元素(因为k%length是从右边数的,从左边就要用length去减)

这时候只需要修改faster.next=head, head=slower.next,slower.next=null就行了

	public ListNode rotateRight(ListNode head, int k) {
        if(head == null) {
            return null;
        }
        
        if(k == 0) {
            return head;
        }
        
        ListNode faster = head;
        ListNode slower = head;
        int length = 1;
        
        while(faster.next != null) {
            faster = faster.next;
            length++;
        }
        
        for(int i = 1; i < (length - k % length); i++) {
            slower = slower.next;
        }
        
        faster.next = head;
        head = slower.next;
        slower.next = null;
        
        return head;
    }

或者如下

    public ListNode rotateRight(ListNode head, int k) {
        if(head == null || head.next == null || k == 0) return head;
        
        ListNode tail = head;
        ListNode newTail = head;
        int length = 1;
        int steps = 0;
        
        while(tail.next != null) {
            tail = tail.next;
            length ++;
        }
        
        steps = length - k % length - 1;
        while(steps > 0) {
            newTail = newTail.next;
            steps --;
        }
        
        tail.next = head;
        head = newTail.next;
        newTail.next = null;
        
        return head;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝羽飞鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值