旋转链表

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

  

  @Data
  public static class ListNode {
    private int val;
    private ListNode next;

    public ListNode(int val) {
      this.val = val;
    }
  }
View Code

 

解法1: 一次一次的把节点向后移动一位,时间复杂度是O((k%n)n)

public static ListNode rotateRight(ListNode head, int k) {
    /*定义一个哑节点*/
    ListNode dumb = new ListNode(0);
    /*哑节点的下一个节点指向头节点*/
    dumb.next = head;
    /*定义一个引用指向哑节点*/
    ListNode h = dumb;
    /*定义一个临时节点指向哑节点*/
    ListNode temp = dumb;
    /*链表长度*/
    int count = 0;
    while (head != null) {
      count++;
      head = head.next;
    }
    /*计算实际要向前走的步数*/
    if (count != 0) {
      k = k % count;
    }
    /*当k不为0时继续循环*/
    while (k > 0) {
      /*尾节点的前一个节点*/
      ListNode finalBefore = null;
      /*头节点*/
      ListNode h1 = temp.next;
      /*当未到达尾节点时继续循环*/
      while (dumb.next != null) {
        /*赋值尾节点的前一个节点*/
        if (dumb.next.next == null) {
          finalBefore = dumb;
        }
        /*引用指向自身的下一个节点*/
        dumb = dumb.next;
      }
      /*当尾节点的前一个节点不为空时,把自己的下一个节点变为null*/
      if (finalBefore != null) {
        finalBefore.next = null;
      }
      /*定义一个引用指向尾节点*/
      ListNode fina = dumb;
      /*当尾节点和头节点相等时,说明链表里只有一个节点,直接返回*/
      if (fina == h1) {
        return fina;
      }
      /*哑节点的下一个节点指向尾节点*/
      temp.next = fina;
      /*尾节点的下一个指向头节点*/
      fina.next = h1;
      k--;
    }
    return h.next;
  }
View Code

 

解法2:把链表结成一个环,用一个指针在环上移动,然后再分开,定义头节点和尾节点,时间复杂度O(n);

public static ListNode rotateRight1(ListNode head, int k) {
    /*判断如果链表里没有元素返回null*/
    if (head == null) {
      return null;
    }
    /*定义一个哑节点*/
    ListNode dumb = new ListNode(0);
    /*哑节点的下一个节点指向头节点*/
    dumb.next = head;
    /*定义一个遍历引用,指向头节点*/
    ListNode traver = head;
    /*链表数量*/
    int total = 1;
    /*计算链表数量且找到尾节点*/
    while (traver.next != null) {
      traver = traver.next;
      total++;
    }
    /*定义一个尾节点引用*/
    ListNode fina = traver;
    /*尾节点的下一个节点指向头节点,形成一个环形链表*/
    fina.next = head;
    /*计算从投节点开始的指针要走的步数*/
    int count = total - k % total - 1;
    /*定义一个指针,赋值头节点*/
    ListNode point = head;
    /*指针沿着环走*/
    while (count > 0) {
      point = point.next;
      count--;
    }
    /*把哑节点的下一个节点指向指针的下一个节点*/
    dumb.next = point.next;
    /*把指针的下一个节点置为null,当作尾节点*/
    point.next = null;
    /*返回哑节点的下一个节点*/
    return dumb.next;
  }
View Code

 

posted @ 2019-11-02 17:38  有为吴  阅读(152)  评论(0编辑  收藏  举报