leetcode912.排序数组的题解

题目描述:

题目要求在不使用任何内置函数的情况下解决问题,时间复杂度为 O(nlog(n))。

笔者使用了快速排序,但是直接使用最原始的快速排序,有些特殊的测试用例会超时。

1)如果数组本身基本有序,则使用原始快速排序算法选取基准的方式,时间复杂度会退化为O(n^2),所以这里使用了随机选取基准点的方式,代码为

int randomIndex = left + rand()%(right-left+1);

swap(nums, left, randomIndex);

2)如果数组中出现了重复元素,速度也会变慢,在得到基准元素、排序之后,在递归调用排序函数前,先去除位置与基准相近、值与基准相同的元素,为什么选取基准呢?笔者认为其他位置的元素不是特别固定,选取基准后、进行一轮排序后,基准前后的元素与基准之间的大小关系是固定的,如果数组中有元素重复,那么在固定基准及其位置后,前后与基准相同的元素与数组前面或后面的大小关系也是确定的,其位置也不用调整了。

所以,最终代码是在原始快速排序基础上加上了随机选取基准点、去除重复元素,代码如下所示:

cpp 复制代码
class Solution {
public:
    void swap(vector<int>& nums, int i, int j) {
        if(i == j) {
            return;
        }
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }

    void quicksort(vector<int>& nums, int left, int right) {
        if(left == right) {
            return;
        }
        int i = left;
        int j = right;
        int randomIndex = left + rand()%(right-left+1);
        swap(nums, left, randomIndex);
        while(i < j) {
            while((i < j) && (nums[j] >= nums[left])) {
                j--;
            }
            while((i < j) && (nums[i] <= nums[left])) {
                i++;
            }
            swap(nums, i, j);
        }
        swap(nums, left, i);
        if(i-left > 1) {
            int left_pivot = i - 1;
            while((left_pivot > left) && (nums[left_pivot] == nums[i])) {
                left_pivot--;
            }
            quicksort(nums, left, left_pivot);
        }
        if(right-i > 1) {
            int right_pivot = i + 1;
            while((right_pivot < right) && (nums[right_pivot] == nums[i])) {
                right_pivot++;
            }
            quicksort(nums, right_pivot, right);
        }
    }

    vector<int> sortArray(vector<int>& nums) {
        srand(time(0));
        quicksort(nums, 0, nums.size()-1);
        return nums;        
    }
};

思考:经典算法、前人经验当然是很好的,能够解决大部分问题,但是总有新的未知的情况出现,那么如何改进经典算法解决现有问题就是一个有趣的事情,把前人的算法理解透彻、算法的每一步的作用、新问题给现有算法带来了哪些挑战、如何改进原有算法既能不影响对于原有测试用例的处理效果又能改进对于新问题的处理效果,怎么办呢,勤学好问、多思考、多见识,把有趣的问题想清楚、弄明白,不贪多求全,找准方向、方法,刻意训练。

相关推荐
纪元A梦2 小时前
贪心算法应用:配送路径优化问题详解
算法·贪心算法
C_player_0012 小时前
——贪心算法——
c++·算法·贪心算法
kyle~3 小时前
排序---插入排序(Insertion Sort)
c语言·数据结构·c++·算法·排序算法
Boop_wu4 小时前
[数据结构] 队列 (Queue)
java·jvm·算法
hn小菜鸡4 小时前
LeetCode 3643.垂直翻转子矩阵
算法·leetcode·矩阵
2301_770373734 小时前
数据结构之跳表
数据结构
散1124 小时前
01数据结构-初探动态规划
数据结构·动态规划
ゞ 正在缓冲99%…5 小时前
leetcode101.对称二叉树
算法
YuTaoShao5 小时前
【LeetCode 每日一题】3000. 对角线最长的矩形的面积
算法·leetcode·职场和发展
2zcode6 小时前
基于Matlab可见光通信系统中OOK调制的误码率性能建模与分析
算法·matlab·php