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;        
    }
};

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

相关推荐
vibecoding日记2 小时前
双非如何快速入职字节等大厂大模型?真实案例分析:推理优化和投机解码
算法·求职·大模型工程师
yszaygr21384 小时前
Verilog参数化游程编码RLE模块
算法
望易4 小时前
刚设计的大模型架构-双域耦合认知框架
算法·架构
复杂网络8 小时前
多个 Claude Code 与多个 Codex 协同工作:设计与实现方案
算法
HjhIron1 天前
面试常客:字符串算法从入门到进阶
算法·面试
吴佳浩1 天前
DeepSeek DSpark:Confidence-Scheduled Speculative Decoding 技术解析
人工智能·算法·deepseek
触底反弹1 天前
🧠 搞懂 Token,才算真正入门大模型——从分词原理到 Embedding 语义实战
javascript·人工智能·算法
vivo互联网技术1 天前
ICLR 2026 | 基于后验采样的图像恢复方法LearnIR:人脸去阴影、去雾
人工智能·算法·aigc
浮生望1 天前
JS字符串与回文算法:从包装类到双指针的面试进阶之路
javascript·算法
黄敬峰1 天前
面试必刷:从JS底层包装类到双指针,彻底搞懂字符串与回文算法
算法