[路飞]_LeetCode题61旋转链表

153 阅读1分钟

题目描述

给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。

示例 1:

image.png

输入:head = [1,2,3,4,5], k = 2 输出:[4,5,1,2,3] 示例 2:

image.png

输入:head = [0,1,2], k = 4 输出:[2,0,1]  

提示:

链表中节点的数目在范围 [0, 500] 内 -100 <= Node.val <= 100 0 <= k <= 2 * 109

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/ro… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

说,要把大象装冰箱,拢共分几步? 要让一个单链表转起来,我们可以想象成一个环形链表,以钟表为模型,以头结点为顶端(12点钟),让链表顺时针转动k次得出新的链表,转动后的新的12点的位置就是新链表的头部,而新头部的上一个节点应该为新链表的尾部,我们只需要将新的尾部与新的头部断开,那新的单链表即为目标链表。

  1. 初始链表

image.png 2. 穿成环后

image.png 3. 顺时针移动k下,k=2

image.png

我们发现,转动两次后,原来的4号位变成了目标链表的头结点,而3号位应该变成目标链表的尾结点,我们需要将3号位断开,假设链表的长度为length

image.png

  1. 我们需要找到链表的尾结点
  2. 让尾结点连接头结点穿成环
  3. 计算出链表长度
  4. 找到目标链表断开的位置,即length-k的位置 说明:由于没有规定k是否小于length,所以我们要将k%length取模处理

题解代码

 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @param {number} k
 * @return {ListNode}
 */
var rotateRight = function(head, k) {
  //说,要把大象装冰箱,拢共分几步?
  //判断节点是否为空
  if(!head) return null;

  //找到链表的尾结点,穿成环
  let cur = head,length = 1;
  while(cur.next){ 
    cur = cur.next;
    length++;
  }//找到尾结点,并计算链表的长度
  cur.next = head;//尾结点指向head穿成环

  //获取到链表的长度,找到length-k的位置,断开链表
  //k%length是为了防止k>length的情况
  for(let i = 0; i< length - k % length - 1; i++){
    head = head.next;
  }
  cur = head.next;//让断开位置的下一个节点成为新的头结点
  head.next = null;//断开链表
  return cur;
};