每日一题 -- 中等 -- 旋转链表(61)

67 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第8天,点击查看活动详情

题目:

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

示例 1:

image.png

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

🙇‍♂️ 感想: 这道题跟昨天做的19题很类似。 也是使用了快慢指针的方式。写了几天链表的题目,感觉稍稍有点找回感觉了,但是还是会有点卡住。继续加油

🙇‍♂️ 解题思路:

  1. 首先循环拿到链表的长度length
  2. 长度与k比较,如果k 大,则只需要旋转 length % k 次 (这里有点脑筋急转弯的意思,我是没有考虑到这个,我用了循环(count - length),一直到 count < lenght 🤣 , 太蠢了,因为这里 时间复杂度增了很多)
  3. 定义一对快慢指针(fast, slow), 首先都指向链表头结点,然后快指针先走count步, 然后判断fast.next是否指向空, 否则快慢指针共同前进,知道fast.next指向空,则slow.next的位置就是要旋转的开始(定义一下从这里开始的链表next), 从这里断开, 并让fast.next指向头结点即可。然后返回next即可
function rotateRight(head: ListNode | null, k: number): ListNode | null {
  if (!head || !head.next || !k) return head
  let link = head
  let length: number = 0
  while(head) {
    length++
    head = head.next
  }
  head = link
  let count =  k < length ? k : k % length // 旋转次数
  if (count) { // 要旋转
    let fast = head, slow = head
    let index = 0
    while (index < count) {
      fast = fast.next
      index++
    }
    while (fast.next) {
      fast = fast.next
      slow = slow.next
    }
    let next = slow.next
    slow.next = null
    fast.next = link
    return next
  }
  return link
};