【链表】LeetCode #61旋转链表

本文详细解析了LeetCode上第61题旋转链表的算法实现,通过双指针技巧寻找链表倒数第k个节点,实现链表的高效旋转。文章包含代码示例及复杂度分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:

LeetCode #61旋转链表

题目描述:

#61. 旋转链表
给定一个链表,旋转链表,将链表每个节点向右移动 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

通过次数77,784 提交次数191,996

分析:

初步分析:

  • 处理k:k %= len
  • 问题转化成把链表的倒数 k 个节点移到前面
  • 如何找倒数第 k 个节点:双指针

关于如何 找到链表的倒数第 k 个节点,之间写过一篇文章:
【链表】LeetCode #19 删除链表的倒数第N个节点(时间复杂度O(n),在所有Java提交中击败了100%的用户)

算法:

  • 求出链表的长度 len
  • k 做取余操作;(比如链表长度为 3k = 4,相当于旋转了一圈多一个,即把倒数第 1 个节点移动到链表表头);
  • 指针 i 指向 headj 指向正数k 个数;
  • i, j 同时向后走,由于两者之间相差 k 个,当 j 走完链表,i 就走到了倒数k 个(灵活运用两个指针 i, j 之间长度差,根据不同的题目要求,决定 j 走到链表最后一个元素,还是走到 null)。

代码:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
 /*
 * k %= len
 * 问题转化成把链表的倒数 k 个节点移到前面
 * 如何找倒数第 k 个节点:双指针
 */
class Solution {
    public ListNode rotateRight(ListNode head, int k) {
        if(head == null || head.next == null) return head;
        ListNode i = head, j = head, cur = head;
        ListNode dummy = new ListNode(-1);
        dummy.next = head;
        int len = 0;
        while(cur != null){
            len++;
            cur = cur.next;
        }
        k %= len;
        for(int l = 0; l < k; l++){ j = j.next;}
        while(j.next != null){
            i = i.next;
            j = j.next;
        }
        j.next = head;
        dummy.next = i.next;
        i.next = null;
        return dummy.next;
    }
}

提交截图:

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

  • 时间复杂度 O(n)
  • 空间复杂度 O(1)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值