2024-10-02

  1. 329. 矩阵中的最长递增路径 - 力扣(LeetCode)
    见上篇 2024-09-30 - 简书 (jianshu.com)
  2. 面试题 04.06. 后继者 - 力扣(LeetCode)
    见上篇 2024-09-30 - 简书 (jianshu.com)
  3. 912. 排序数组 - 力扣(LeetCode)
    排序一:冒泡排序==稳定==n^2==1
class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        return bubbleSort(nums);
    }

private:
    vector<int> bubbleSort(vector<int>& nums) {
        int n = nums.size();
        for (int i = 0; i < n - 1; i++) {
            bool flag = false;
            for (int j = 0; j < n - 1 - i; j++) {
                if (nums[j] > nums[j + 1]) {
                    swap(nums[j], nums[j + 1]); // 稳定
                    flag = true;
                }
            }
            if (flag == false) break;
        }
        return nums;
    }
};

排序二:选择排序==不稳定==n^2==1

class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        return selectSort(nums);
    }

private:
    vector<int> selectSort(vector<int> &nums) {
        int n = nums.size();
        for (int i = 0; i < n - 1; ++i) {
            int minIndex = i;
            for (int j = i + 1; j < n; ++j) 
                if (nums[j] < nums[minIndex])
                    minIndex = j;
            swap(nums[i], nums[minIndex]); // 不稳定
        }
        return nums;
    }
};

排序三:插入排序==稳定==n^2==1

class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        return insertSort(nums);
    }

private:
    vector<int> insertSort(vector<int>& nums) {
        int n = nums.size();
        for (int i = 1; i < n; i++)
            for (int j = i; j > 0; j--)
                if (nums[j - 1] > nums[j]) // 稳定
                    swap(nums[j - 1], nums[j]);
                else break; // !!!
        return nums;
    }
};

排序四:希尔排序==不稳定==nlogn和n^2之间==1

class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        return shellSort(nums);
    }

private:
    vector<int> shellSort(vector<int>& nums) {
        int n = nums.size();
        for (int gap = n / 2; gap > 0; gap /= 2)
            for (int i = gap; i < n; i++)
                for (int j = i; j - gap >= 0; j -= gap)
                    if (nums[j - gap] > nums[j])
                        swap(nums[j - gap], nums[j]); // 不稳定
                    else break; // !!!
        return nums;
    }
};

排序五:归并排序==稳定==nlogn==n

class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        int left = 0, right = nums.size() - 1;
        mergeSort(nums, left, right);
        return nums;
    }

private:
    void mergeSort(vector<int>& nums, int left, int right) {
        if (left >= right) return;
        int mid = (left + right) / 2;
        mergeSort(nums, left, mid);
        mergeSort(nums, mid + 1, right);
        merge(nums, left, mid, right);
    }

    void merge(vector<int>& nums, int left, int mid, int right) {
        // nums[left...mid] nums[mid+1...right]
        int size = right - left + 1;
        vector<int> temp(size);
        int i = left, j = mid + 1, k = 0;
        for (; k < size; k++)
            if (j > right || (i <= mid && nums[i] <= nums[j])) // 稳定
                temp[k] = nums[i++];
            else
                temp[k] = nums[j++];
        for (k = 0; k < size; k++)
            nums[left + k] = temp[k];
    }
};

排序六:堆排序-不稳定-nlogn-1
法一:优先队列

class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        heapSort(nums);
        return nums;
    }

private:
    void heapSort(vector<int>& nums) {
        int n = nums.size();
        priority_queue<int> q;
        for (int i = 0; i < n; i++) q.push(-nums[i]);
        for (int i = 0; i < n; i++) {
            nums[i] = -q.top();
            q.pop();
        }
    }
};

法二:自实现二叉堆

class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        heapSort(nums);
        return nums;
    }

private:
    void heapSort(vector<int>& nums) {
        int n = nums.size();
        for (int i = n / 2 - 1; i >= 0; i--) 
            heapifyDown(nums, i, n);
        for (int i = n - 1; i >= 0; i--) {
            swap(nums[0], nums[i]); // 不稳定
            heapifyDown(nums, 0, i);
        }
    }

    void heapifyDown(vector<int>& nums, int index, int size) {
        int left = index * 2 + 1, right = index * 2 + 2;
        int max = index;
        if (left < size && nums[left] > nums[max])
            max = left;
        if (right < size && nums[right] > nums[max])
            max = right;
        if (max != index) {
            swap(nums[max], nums[index]);
            heapifyDown(nums, max, size);
        }
    }
};

排序七:快速排序==不稳定==nlogn==logn

class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        quickSort(nums, 0, nums.size() - 1);
        return nums;
    }

private:
    void quickSort(vector<int>& nums, int left, int right) {
        if (left >= right) return;
        int pivot = partition(nums, left, right);
        quickSort(nums, left, pivot); // A
        quickSort(nums, pivot + 1, right);
    }

    int partition(vector<int>& nums, int left, int right) {
        int pivot = left + rand() % (right - left + 1);
        int pivotVal = nums[pivot];
        while (left <= right) {
            while (nums[left] < pivotVal) left++; // 此处代入pivotVal一起排序,所以为<,A处同理
            while (nums[right] > pivotVal) right--;
            if (left < right) {
                swap(nums[left], nums[right]);
                left++; right--;
            }
            else break;
        }
        return right;
    }
};

排序八:计数排序==稳定==(n+k)==(k)
k=maxNum-minNum+1

class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        int minVal = INT_MAX, maxVal = INT_MIN;
        for (int num : nums) {
            minVal = min(minVal, num);
            maxVal = max(maxVal, num);
        }
        vector<int> temp(maxVal - minVal + 1);
        for (int num : nums) temp[num - minVal]++;
        int k = 0;
        for (int i = 0; i < temp.size(); i++)
            while (temp[i] > 0) {
                nums[k++] = minVal + i;
                temp[i]--;
            }
        return nums;
    }
};
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • [toc] 范围 优先级队列,二分搜索,滑动窗口,双指针,单调栈不会考动规了,贪心和BFS/DFS我考这么多次也没...
    ttyttytty阅读 1,781评论 0 0
  • 排序方法 冒泡排序 选择排序 堆排序 插入排序 归并排序 快速排序 希尔排序 计数排序 基数排序 桶排序 初识排序...
    AlanGe阅读 3,928评论 0 1
  • [TOC] 初识排序 什么叫排序? 排序前:3,1,6,9,2,5,8,4,7 排序后:1,2,3,4,5,6,7...
    贾里阅读 3,430评论 0 0
  • 本文总结十大经典排序算法及变形,并提供Java实现。参考文章:十大经典排序算法总结(Java语言实现)快速排序算法...
    Steven1997阅读 17,805评论 3 185
  • 排序是最基础的算法,但是如果长时间不写不看,很容易忘掉原理、忘掉代码。这里汇总一下常见的排序算法,并列出其时间空间...
    舞鹤Roc阅读 1,150评论 0 0