Insert into a Cyclic Sorted List

update Jul 24, 2017 15:40

LintCodearrow-up-right

Given a node from a cyclic linked list which has been sorted, write a function to insert a value into the list such that it remains a cyclic sorted list. The given node can be any single node in the list. Return the inserted new node.

Notice

  • 3->5->1 is a cyclic list, so 3 is next node of 1.

  • 3->5->1 is same with 5->1->3

Example

Given a list, and insert a value 4:
3->5->1
Return 5->1->3->4

Basic Idea:

  1. 考虑当输入是null时的情况

  2. 当可以找到 curr <= target <= next 时的情况

  3. target 比所有node值都大或者都小的情况

update 2017-11-21 01:59:08

这道题其实没有想象中的那么简单,而奇怪的是几个月前第一次刷这道题的时候还用一个错误解骗过了LintCode 的 OJ,导致一直没有发现问题。

问题在于:

首先我们考虑共有哪些情况 :

  1. node is None;

  2. 我们找到了明确可以插入的位置:curr.val <= x <= curr.next.val;

  3. x 比当前 linked list 的所有元素都大,或者都小;

看到这里感觉还是没有问题的,和之前的分析也一样,但是关键就在于如何判断 x 比所有当前元素都大或者都小,此时需要分两种情况讨论:

  1. 给定 list 的元素不全都相同,例如 3,1,5;

    这种情况我们可以通过判断 curr.val > curr.next.val 来确定是否到达排序链表的 tail,然后分别判断 x 是否比 curr 和 curr.next 都大或者都小;

  2. 给定 list 所有元素都相同,这种情况下就很容易出现死循环;

    这种情况下,我们就需要记录一开始给定的 node,当出现 curr is node 的时候,我们就知道我们一定已经循环了一整圈,并且不符合以上其他情况,那么一定是因为给定list所有元素都相同,无法判断出tail导致,此时可以直接插入 x;

综上所述

正确的做法其实是使用多个判断语句分情况讨论:

  1. 如果 curr is node,说明已经一圈结束,且所有元素都相同,可以插入;

  2. curr.val <= x <= curr.next.val,即恰好有位置插入;

  3. 如果已经到 tail: curr.val > curr.next.val,继续判断 首位两元素是否都大于或者都小于 x,如果是,则可以插入;

Java Code:

Python Code:

update 2017-11-21 14:18:45

总结

面对一道题的时候,应该在动手coding之前先想好所有的可能情况,有了通盘考虑之后再开始动手。

update 2018-6-30 22:27

Update

一种新的想法:

其实如果给定list的元素种类不是唯一的,就一定可以在一次循环中搞定,那么如果在循环结束(回到给定node)后没有搞定,则说明list中元素是唯一的,此时就可以直接插入;

所以在实现的时候,先用一层while循环处理list中元素不唯一的情况,如果在这次循环中没有解决,则直接插入target;