📜  门| GATE-CS-2006 |第 31 题(1)

📅  最后修改于: 2023-12-03 15:42:16.112000             🧑  作者: Mango

题目描述

给定一个数组arr和一个数num,请将小于等于num的数放到数组的左边,大于num的数放到数组的右边,并返回最终的分界线下标。要求时间复杂度O(n),空间复杂度O(1)。

示例

输入:arr=[1,3,2,6,5,2], num=3

输出:2

说明:分界线下标为2,小于等于3的数包括1、3、2,大于3的数包括6、5、2,分界线位置右侧是大于3的数,左侧是小于等于3的数。

解题思路

题目要求O(n)时间复杂度,考虑使用指针对数组进行遍历与操作。

具体思路是使用两个指针指向数组头尾,当左边指针扫到大于num的数时,停止遍历,此时右边指针开始往左扫,直到扫到小于等于num的数,利用左右指针交换两个数的位置,直到左右指针相互交错,此时遍历完成。

代码实现

def partition(arr, num):
    left, right = 0, len(arr) - 1 #左右指针
    while left <= right:
        if arr[left] <= num:
            left += 1
        elif arr[right] > num:
            right -= 1
        else:
            arr[left], arr[right] = arr[right], arr[left]
            left += 1
            right -= 1
    return left - 1 #返回分界线下标

复杂度分析

该算法时间复杂度为O(n),空间复杂度为O(1)。由于只需要交换数的位置,而不是进行数的比较,因此效率较高。