目录

LC 剑指 Offer II 029. 排序的循环链表 (opens new window) (opens new window)

中等

# 问题描述

给定循环单调非递减列表中的一个点,写一个函数向这个列表中插入一个新元素 insertVal ,使这个列表仍然是循环升序的。

给定的可以是这个列表中任意一个顶点的指针,并不一定是这个列表中最小元素的指针。

如果有多个满足条件的插入位置,可以选择任意一个位置插入新的值,插入后整个列表仍然保持有序。

如果列表为空(给定的节点是 null),需要创建一个循环有序列表并返回这个节点。否则。请返回原先给定的节点。

示例 1:

示例1

输入:head = [3,4,1], insertVal = 2
输出:[3,4,1,2]
解释:在上图中,有一个包含三个元素的循环有序列表,你获得值为 3 的节点的指针,我们需要向表中插入元素 2 。新插入的节点应该在 1 和 3 之间,插入之后,整个列表如上图所示,最后返回节点 3 。

示例1

示例 2:

输入:head = [], insertVal = 1
输出:[1]
解释:列表为空(给定的节点是 null),创建一个循环有序列表并返回这个节点。

示例 3:

输入:head = [1], insertVal = 0
输出:[1,0]

提示:

  • 0 <= Number of Nodes <= 5 * 104
  • -106 <= Node.val <= 106
  • -106 <= insertVal <= 106

注意:本题与主站 708 题相同:https://leetcode-cn.com/problems/insert-into-a-sorted-circular-linked-list/ (opens new window)

# 一次遍历

分情况讨论进行处理:

  • headhead 为空时,创建一个新的值为 insertValinsertVal 的节点,并将它的 nextnext 指向自己,形成循环链表,返回该节点。
  • headhead 不为空时,遍历链表,使用 currcurr 表示当前遍历到的节点,有以下几种情况:
    • 若链表中存在某个地方,使得值为 insertValinsertVal 的节点插入后依然使得循环链表满足单调非递减,即 curr.val<=insertVal<=curr.next.valcurr.val <= insertVal <= curr.next.val,此时创建值为 insertValinsertVal 的节点,将节点的 nextnext 指向curr.nextcurr.next,再插入到 $curr 之后。
    • 若链表不存在某个地方,使得值为 insertValinsertVal 的节点插入后依然使得循环链表满足单调非递减,那么 insertValinsertVal 必然是大于等于链表中的最大值或小于等于链表中的最小值,能插入的地方只有是当前链表最大最小值交汇的地方,该位置curr.val>curr.next.valcurr.val > curr.next.val,此时创建值为 insertValinsertVal 的节点,将该节点的 nextnext 指向 curr.nextcurr.next,再插入到 currcurr 之后。
    • 若链表循环了一圈 (curr.next==head)(curr.next == head),依然没找到能够插入的点,此时链表中的所有值都相同,只需将创建值为 insertValinsertVal 的节点插入到任意位置即可,因为最终判断是在 curr.next==headcurr.next == head 的情况,所以将新创建的值为 insertValinsertVal 的节点插入到 currcurr 之后,该节点的 nextnext 指向 headhead 形成循环链表即可
/**
 * // Definition for a Node.
 * function Node(val, next) {
 *     this.val = val;
 *     this.next = next;
 * };
 */

/**
 * @param {Node} head
 * @param {number} insertVal
 * @return {Node}
 */
var insert = function (head, insertVal) {
  if (!head) {
    head = new Node(insertVal)
    head.next = head
    return head
  }
  let curr = head
  while (true) {
    if (curr.next === head) {
      const node = new Node(insertVal)
      node.next = head
      curr.next = node
      return head
    } else if (
      (curr.val <= insertVal && insertVal <= curr.next.val) ||
      (curr.val > curr.next.val && (insertVal >= curr.val || insertVal <= curr.next.val))
    ) {
      const node = new Node(insertVal)
      node.next = curr.next
      curr.next = node
      return head
    } else {
      curr = curr.next
    }
  }
}
  • 时间复杂度:O(n)O(n),需要遍历链表一次找到能够插入的节点。
  • 空间复杂度:O(1)O(1)
上次更新: 2023/01/31 19:48:05

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 , 转载请注明出处!