我今天在一次采访中被问到这一点,我开始相信这是无法解决的
给定一个大小为n
的排序数组,选择数组中的k
元素,并将它们重新排列回数组中,生成一个新的“nk排序”数组
查找在新数组中移动的k(或更少)个元素
下面是创建此类数组的(Python)代码,但我不关心用于此的语言
import numpy as np
def __generate_unsorted_array(size, is_integer=False, max_int_value=100000):
return np.random.randint(max_int_value, size=size) if is_integer else np.random.rand(size)
def generate_nk_unsorted_array(n, k, is_integer=False, max_int_value=100000):
assert k <= n
unsorted_n_array = __generate_unsorted_array(n - k, is_integer, max_int_value=max_int_value)
sorted_n_array = sorted(unsorted_n_array)
random_k_array = __generate_unsorted_array(k, is_integer, max_int_value=max_int_value)
insertion_inds = np.random.choice(n - k + 1, k, replace=True) # can put two unsorted next to each other.
nk_unsorted_array = np.insert(sorted_n_array, insertion_inds, random_k_array)
return list(nk_unsorted_array)
这在复杂性约束下可行吗
这只是问题的一部分。对O(n+klogk)
中的“nk排序数组”进行排序所需的整个问题
即使@Gulzar's solution是正确的,它实际上并没有给我们} 。这使得整个算法的复杂度为
O(n + k * log k)
。 问题出在sort_nk_unsorted_list
函数中。不幸的是,从Python列表中删除任意项不是固定时间It's actually ^{O(n + nk + k * log k)
要解决这个问题,我们可以使用不同的数据结构。如果使用双链接列表,则从该列表中删除项目实际上是
O(1)
。不幸的是,Python在默认情况下没有附带一个这是我的解决方案,它实现了
O(n + k * log k)
解决问题的入口点函数:
将有序元素与无序元素分开的函数:
合并两个单独列表的函数:
最后,这是DoublyLinkedList实现(我使用了sentinel节点使事情变得更简单):
以下是我用来验证代码的单元测试:
注意:这是一个概念性的解决方案。它是用Python编码的,但由于Python实现List的方式,实际上并没有以所需的复杂度运行。请参见soyuzzzz's answer以查看复杂性需求中Python的实际解决方案
接受了@Soyuzzz的回答
原始答案(可行,但复杂度仅在假设Python列表的链表实现时正确,事实并非如此):
这将对
O(n + klogk)
中的nk未排序数组进行排序,假设该数组应该是升序的O(n)
时间内保留2k个元素李>O(klogk)
O(n)
O(n + klogk)
代码:
及
相关问题 更多 >
编程相关推荐