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

leetcode网解题心得——61. 旋转链表

1、题目描述

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

试题链接:https://leetcode-cn.com/problems/rotate-list/

2、算法分析:

为了完成该算法,在进行代码编写时先进行了数学分析,下面照片是数学分析的草稿,图可能有些丑。

下面解释下该图:

  1. 由于题目是循环列表,可以将单链表进行打断,组成一个圆圈。而指针所指的方向即是起点。
  2. 模拟循环,由循环后的结果可以得出,如果循环次数恰好为一圈时等于没循环。
  3. 同时,可以很简单的看出,k=几,就相当于顺时针转动k步
  4. 由于单链表只是一侧的,在图上更方便逆时针转动,因此可计算出逆时针转动的步数=角-k

3、用自然语言描述该算法

  1. 先求得链表的长度,即为多边形角度
  2. 遍历单链表,到最后一个位置,然后将指向修改为指向头结点,打造成环形链表
  3. 由分析计算出来的公式,逆时针将辅助指针旋转角度-k-1步,位于所要的结果前一个
  4. 保存下一个结点,因为打断后无法过去,需要先保存
  5. 打断循环链表,返回保存的结点

4、java语言实现

    public static ListNode rotateRight(ListNode head, int k) {
        if(head == null) return null;
        //1,需要知道链表的长度
        ListNode pCurrent = head;
        int count = 1;
        while(pCurrent.next != null) {
            //计数
            count++;
            //向下
            pCurrent = pCurrent.next;
        }
        //循环结束后,指向的是最后一个结点,对接成循环链表
//        System.out.println(count);
        pCurrent.next = head;
        //指向头,循环链表
        pCurrent = pCurrent.next;
        //计算有效循环
        int total = k % count;
        //计算顺转次数
        total = count - total;
//        System.out.println(total);
        for(int i = 1;i < total;i++) {
            pCurrent = pCurrent.next;
        }
        //保存下一个结点
        ListNode saveNode = pCurrent.next;
        pCurrent.next = null;
        return saveNode;
    }

算法效果:

算法分析,时间上还行,但是空间上消耗较大。

5、C语言实现

struct ListNode* rotateRight(struct ListNode* head, int k){
    if(head == NULL) return NULL;
    //1,需要知道链表的长度
    struct ListNode* pCurrent = head;
    int count = 1;
    while(pCurrent->next != NULL) {
        //计数
        count++;
        //向下
        pCurrent = pCurrent->next;
    }
    //循环结束后,指向的是最后一个结点,对接成循环链表
//        System.out.println(count);
    pCurrent->next = head;
    //指向头,循环链表
    pCurrent = pCurrent->next;
    //计算有效循环
    int total = k % count;
    //计算顺转次数
    total = count - total;
//        System.out.println(total);
    for(int i = 1;i < total;i++) {
        pCurrent = pCurrent->next;
    }
    //保存下一个结点
    struct ListNode* saveNode = pCurrent->next;
    pCurrent->next = NULL;
    return saveNode;
}

算法效果:

算法分析:根据C语言的提交结果可知,在时间和内存消耗上都较为一般

版权声明:本文为xgp123原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/xgp123/p/12374359.html