434
社区成员
发帖
与我相关
我的任务
分享从数组中选择中间元素作为枢轴。
将数组划分为两部分,左边都是小于枢轴的元素,右边都是大于枢轴的元素。划分结束后,枢轴所在的位置就是其在排序数组中的正确位置。
根据枢轴的位置和第k小的数的索引关系,决定下一步递归的方向:
如果枢轴的位置恰好为k-1(因为数组索引从0开始),则完成搜索。
如果枢轴的位置大于k-1,说明第k小的元素在枢轴的左侧,递归地在左侧子数组中查找。
如果枢轴的位置小于k-1,说明第k小的元素在枢轴的右侧,递归地在右侧子数组中查找,并更新k的值为k减去枢轴左侧元素的数量。
int pivotIndex = partition(nums, left, right);
// 检查基准是否是第k小的元素
if (k == pivotIndex + 1) {
return nums[k - 1]; // 注意数组是从0开始索引的,所以要减1
} else if (k < pivotIndex + 1) {
// 如果k在基准的左边,那么递归地在左子数组中查找
return quickSelect(nums, left, pivotIndex - 1, k);
} else {
// 如果k在基准的右边,那么更新k的值,并在右子数组中查找
return quickSelect(nums, pivotIndex + 1, right, k - pivotIndex - 1 + left);
}
当数组的大小缩小到只有k个元素时,返回枢轴,即为所求的第k小的元素。
最好时间复杂度是 O(n)。这是在划分操作后,枢轴元素恰好是第k小的元素时的情况。在这种情况下,不需要进行任何递归调用,直接返回该枢轴元素即可。
最坏时间复杂度是 O(n^2)。这种情况发生在每次划分操作中,选择的枢轴元素总是最大或最小元素之一,导致每次只排除一个元素。例如,如果数组已经排序,且每次选择的枢轴元素总是当前数组的最小或最大元素,那么需要进行n-1次划分,每次划分都将数组的大小减少1,导致总的复杂度为O(n^2)。
分治法通过递归地将问题划分为更小的子问题来解决,这可以显著提高解决问题的效率,尤其是在平均情况下。例如,快速选择算法在平均情况下的时间复杂度为O(n),这比全数组排序后再查找要快得多。
分治法通过将复杂问题简化为相同问题的较小实例来简化问题解决过程。
分治算法通常涉及递归
许多的算法都涉及到分治思想