面试题精选(85):给定数组Arr[n],O(n)时间内找出每个元素左侧所有元素中位置最靠近该元素且大于该元素的元素

题目:

     给定数组Arr[n],对于其中的每个元素Arr[i](0=<i<n),在Arr[0...i-1]中找到元素Arr[k],Arr[k]满足Arr[k]>Arr[i],并且i-k值最小(即最靠近)。

     要求O(n)时间内找出Arr中所有元素对应的Arr[k]的位置。

     ex,

     src[]: 9, 5, 2, 4, 7

     dst[]: -1,0, 1, 1, 0

 

思路:

     借助于栈来实现,从后向前遍历数组,while栈顶元素小于当前遍历的数组元素,则更新dst,并pop。

参见下面代码

 

 

代码:

 

题目描述的是一个经典的计算机科学问题,叫做“第K小/大”(或称为“最小/最大堆”)的问题,有时也被称为“快速选择”(QuickSelect)。这个算法的目标是在平均情况下达到线性时间复杂度O(n),但是最坏情况下的时间复杂度为O(n^2)。 解决方案通常使用分治策略,结合随机化技术来避免最坏情况的发生。基本步骤如下: 1. **随机选择基准** (pivot):从n个元素随机选取一个作为当前的基准值。 2. **分区操作**:根据基准值将数组分为两个子数组,一个包含所有小于基准值的元素,另一个包含大于等于基准值的元素。 3. **判断基准位置**: - 如果基准值的位置正好是k-1,那么找到了第k小的元素。 - 如果k-1比基准值小,说明第k小的元素在左子数组里,继续在左子数组进行相同的操作。 - 如果k-1比基准值大,说明第k小的元素在右子数组里,但在左子数组元素数量加1,然后在右子数组进行相同的操作。 重复以上步骤直到找到第k小的元素。这种方法的关键在于每次划分后,都能缩小搜索范围,从而达到平均线性的期望性能。 下面是简单的伪代码示例: ```plaintext function quick_select(arr, k): if arr.length == 1: return arr[0] pivot_index = random.randint(0, arr.length - 1) pivot = arr[pivot_index] smaller, equal, larger = [], [], [] for i in range(len(arr)): if i != pivot_index: if arr[i] < pivot: smaller.append(arr[i]) else: larger.append(arr[i]) if k <= len(smaller): return quick_select(smaller, k) elif k <= len(smaller) + 1: return pivot else: return quick_select(larger, k - len(smaller) - 1) ``` 请注意,上述代码并未提供完整的C语言版本,因为实际编写时需要处理边界条件、递归调用等细节。如果你需要C语言的完整实现,我可以帮助你写出一段代码。但在此之前,请确认是否已经了解了这个算法的基本原理,以及是否需要具体的编程实现指导?
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值