📅  最后修改于: 2023-12-03 15:27:34.390000             🧑  作者: Mango
假设我们已经有一个按照升序排列的链表,现在我们需要按照相同的方式插入一个新元素。这个问题具有一些简单的解法,但如果我们考虑插入效率和算法复杂度,那就需要花点时间研究。
最简单的解决方案是遍历链表,找到第一个大于等于当前元素的节点,然后将新元素插入到该节点之前。
def insert_sorted(head, val):
new_node = ListNode(val)
if val <= head.val:
new_node.next = head
return new_node
curr = head
while curr.next and curr.next.val < val:
curr = curr.next
new_node.next = curr.next
curr.next = new_node
return head
复杂度分析
第二种解决方案利用链表已经按升序排列的特点,可以使用二分查找来找到元素插入位置。我们从链表的中间开始,尝试找到大于等于新元素的节点,然后继续在该节点左侧或右侧继续查找。
def insert_sorted(head, val):
new_node = ListNode(val)
if val <= head.val:
new_node.next = head
return new_node
l, r = head, None
while l:
if l.val >= val:
new_node.next = l
r.next = new_node if r else new_node
return head
r, l = l, l.next
r.next = new_node
return head
复杂度分析
第三种解决方案使用双指针,一个指针指向链表的头,另一个指针指向当前节点。我们遍历链表,找到第一个不小于新元素的节点,然后将新元素插入到该节点前面。
def insert_sorted(head, val):
new_node = ListNode(val)
dummy = ListNode(0, head)
prev, curr = dummy, head
while curr and curr.val < val:
prev, curr = curr, curr.next
prev.next, new_node.next = new_node, curr
return dummy.next
复杂度分析
以上三种解决方案都是可行的,它们的时间复杂度和空间复杂度也都不错。但双指针的解决方案最简洁,代码最短。所以,我们在面对这个问题时,可以优先考虑使用双指针算法。