leetcode_061 Rotate List

题目分析:

  • 给定一个链表,从链表尾端数k个节点位置,从该位置开始到结尾和之前的那部分对调。实质为链表的在某个位置旋转操作。

解题思路:

  • 方法1:将链表链接成环再旋转

    1)遍历链表,将链表的表尾和链表的表头相连,同时记录链表的表长

    2)计算链表旋转后的处于的起始位置,然后从头遍历链表到逆转的位置前一个节点位置,即(len - k - 1)处;

    3)记录链表的新表头,并断开环状链表即可。

  • 方法2:直接定位旋转

    1)遍历链表,找k所在的位置

    2)遍历接受后,判断当前cur节点是否为空,如果为空,则可能是k值大于len导致,故令k = k % len,然后从头遍历链表到k - 1位置;否则直接处理步骤3);

    3)从表头开始遍历链表,找到旋转所在位置的前一个元素位置;

    4)将链表的表尾与表头相连接,然后记录新的表头所在的位置,同时将新的链表的表尾置空,返回新链表即可。

    注意:实现过程中,注意对k取特殊值的处理即可。

  • 实现程序

    // 方法1:先将链表链接成环再旋转 
    ListNode *rotateRight1(ListNode *head, int k)
    {
        if (head == NULL || k == 0)
            return head; 
        struct ListNode *p = head;
        // 统计链表长度 
        int len = 1; 
        while (p->next != NULL)
        {
            p = p->next;
            len++;
        }
        // 将链表链接成环 
        p->next = head;
        // 计算实际的位置k 
        if (k >= len)
            k = k % len;
        if (k == 0)
        {
            p->next = NULL;
            return head;
        }
        // 从表头遍历链表,定位到逆转的前一个位置值 
        int i = 1;
        p = head;
        while (i < len - k)
        {
            p = p->next;
            i++;
        }
        // 记录逆转后的头结点 
        head = p->next;
        // 断开环状链表 
        p->next = NULL;
        return head; 
    }
    // 方法2:直接查找位置,进行相关旋转 
    ListNode *rotateRight(ListNode *head, int k)
    {
        // 特殊情况处理 
        if (head == NULL || k == 0)
            return head;
        // pre用于记录最后旋转的位置 
        struct ListNode *pre = head;
        // 遍历用于找位置 
        struct ListNode *cur = head;
        int count = 0;
        // 遍历链表寻找k位置 
        while (cur != NULL && count < k)
        {
            cur = cur->next;
            count++;
        }
        // 已经遍历到链表的尾部,可能count未达到k,此时count为链表长度 
        if (cur == NULL)
        {
            // 计算真正k的位置 
            k = k % count;
            cur = head;
            count = 0;
            // 从表头遍历,找到真正的k位置 
            while (cur != NULL && count < k)
            {
                cur = cur->next;
                count++;
            }
        }
        // 找到为逆转所在的位置,即len - k位置 
        while (cur->next != NULL)
        {
            pre = pre->next;
            cur = cur->next;
        }
        // 将链表首尾相接 
        cur->next = head;
        // 记录新的表头位置 
        head = pre->next;
        // 新链表的表尾置空 
        pre->next = NULL;
        // 返回新链表 
        return head;
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值