前端算法面试必刷题系列[23]

292 阅读2分钟

这个系列没啥花头,就是纯 leetcode 题目拆解分析,不求用骚气的一行或者小众取巧解法,而是用清晰的代码和足够简单的思路帮你理清题意。让你在面试中再也不怕算法笔试。

40. 旋转链表 (rotate-list)

标签

  • 链表操作

题目

leetcode 传送门

这里不贴题了,leetcode打开就行,题目大意:

给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。 由于是循环旋转最终状态其实是确定的,利用链表的长度取余可以得到链表的最终旋转结果

画图解析

链表题一定要画图,模拟指针移动过程,写出1,2,3 步,就很清晰明了。

基本思路是

  1. 先将链表闭合成环
  2. 找到相应的位置断开这个环,确定新的链表头和链表尾

image.png

基本步骤

  1. 找到旧的尾部并将其与链表头相连 oldTail.next = head,整个链表闭合成环,同时计算出链表的长度
  2. 找到新的尾部,第 (len - k % n - 1) 个节点 ,新的链表头是第 (len - k % n) 个节点。
  3. 断开环 newTail.next = null,并返回新的链表头 newHead

写法实现

/**
 * @param {ListNode} head
 * @param {number} k
 * @return {ListNode}
 */
var rotateRight = function(head, k) {
  // 特判,下面3种情况,直接返回head
  if (head === null || head.next === null || k === 0) {
    return head;
  }

  // oldTail 是初始链表的末尾,我们经过循环
  // 1. 得到链表长度 len,注意指到头时len已经是 1 了
  let oldTail = head, len = 1;
  while (oldTail.next !== null) {
    oldTail = oldTail.next;
    len++;
  }
  // 2. 把原末尾接到头上,形成环
  oldTail.next = head;

  // 现在的尾应该是 (n - k % n - 1) 个节点位置,头就是尾的下一个位置
  // 为什么用取模运算? k > len 时,去掉他转圈len / k的倍数整除部分
  // 只需要考虑 k%n 的部分,这个值一定比 len 小。

  let nowTail = head;
  for (let i = 0; i < len - k % len - 1; i++) {
    nowTail = nowTail.next;
  }
  nowHead = nowTail.next;
  
  // 将环断开,现在的尾部指向null
  nowTail.next = null

  return nowHead
};

另外向大家着重推荐下这位大哥的文章,非常深入浅出,对前端进阶的同学非常有作用,墙裂推荐!!!核心概念和算法拆解系列

今天就到这儿,想跟我一起刷题的小伙伴可以加我微信哦 搜索我的微信号infinity_9368,可以聊天说地 加我暗号 "天王盖地虎" 下一句的英文,验证消息请发给我 presious tower shock the rever monster,我看到就通过,暗号对不上不加哈,加了之后我会尽我所能帮你,但是注意提问方式,建议先看这篇文章:提问的智慧

参考