专题七_分治-快排

目录

75. 颜色分类

解析

题解

912. 排序数组

解析

题解

215. 数组中的第K个最大元素

解析

题解

LCR 159. 库存管理 III(最小的k个数)

解析

题解


75. 颜色分类

75. 颜色分类

解析

题解

class Solution {
public:
    void sortColors(vector<int>& nums) {
        // 专题七_分治-快排_颜色划分_C++
        // [0 - left] : 全是 0
        // [left+1 - i-1] : 全是 1
        // [i - right-1] : 未扫描的区域
        // [right - n--1] : 全是 2
        int left = -1, i = 0, right = nums.size();
        while(i < right)
        {
            if (nums[i] == 0) swap(nums[++left], nums[i++]);
            else if (nums[i] == 1) i++;
            else swap(nums[i], nums[--right]);
        }
    }
};

912. 排序数组

912. 排序数组

解析

题解

class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        // 46.专题七_分治-快速_快速排序_C++
        srand(time(NULL));
        qsort(nums, 0, nums.size() - 1);
        return nums;
    }
    void qsort(vector<int>& nums, int l, int r)
    {
        if (l >= r) return;

        // 数组分三块
        int key = getRandom(nums, l, r);
        int i = l, left = l - 1, right = r + 1;
        while (i < right)
        {
            if (nums[i] < key) swap(nums[i++], nums[++left]);
            else if (nums[i] == key) i++;
            else swap(nums[i], nums[--right]);
        }

        // [l, left] [left + 1, right - 1] [right, r]
        qsort(nums, l, left);
        qsort(nums, right, r);
    }

    int getRandom(vector<int>& nums, int left, int right)
    {
        int r = rand();
        return nums[r % (right - left + 1) + left];
    }
};

215. 数组中的第K个最大元素

215. 数组中的第K个最大元素

解析

题解

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        // 47.专题七_分治-快排_快速选择算法_C++
        srand(time(NULL));
        return qsort(nums, 0, nums.size() - 1, k);
    }

    int qsort(vector<int>& nums, int l, int r, int k)
    {
        if (l == r) return nums[l];
        // 1. 随机选择基准元素
        int key = GetRandom(nums, l, r);
        // 2. 根据基准元素将数组分三块
        int i = l, left = l - 1, right = r + 1;
        while (i < right)
        {
            if (nums[i] < key) swap(nums[i++], nums[++left]);
            else if (nums[i] == key) i++;
            else swap (nums[i], nums[--right]);
        }
        // 3. 分情况讨论
        // [l, left] [left + 1, right - 1] [right, r]
        // a:区间个数         b               c
        int c = r - right + 1, b =  right - left - 1;  // 原式: right - 1 - (left + 1) + 1
        if (c >= k) return qsort(nums, right, r, k);
        else if (b + c >= k) return key; // 直接就找到了
        else return qsort(nums, l, left, k - b - c);
    }

    int GetRandom(vector<int>& nums, int left, int right)
    {
        return nums[rand() % (right - left) + left];
    }

};

LCR 159. 库存管理 III(最小的k个数)

LCR 159. 库存管理 III

解析

题解

class Solution {
public:
    vector<int> inventoryManagement(vector<int>& stock, int cnt) {
        srand(time(NULL));
        qsort(stock, 0, stock.size() - 1, cnt);
        return {stock.begin(), stock.begin() + cnt};
    }

    void qsort(vector<int>& stock, int l, int r, int cnt)
    {
        

        // 1. 随机选择基准元素
        int key = GetRandom(stock, l, r);
        // 2. 根据基准元素将数组分三块
        int i = l, left = l - 1, right = r + 1;
        while (i < right)
        {
            if (stock[i] < key) swap(stock[i++], stock[++left]);
            else if (stock[i] == key) i++;
            else swap (stock[i], stock[--right]);
        }
        // 3. 分情况讨论
        // [l, left] [left + 1, right - 1] [right, r]
        // a:区间个数         b               c
        int a = left - l + 1, b = right - left - 1; // right - 1 - (left + 1) + 1
        if (a > cnt) qsort(stock, l, left, cnt);
        else if (a + b >= cnt) return;
        else qsort(stock, right, r, cnt - a -b);
    }
    
    int GetRandom(vector<int>& stock, int left, int right)
    {
        return stock[rand() % (right - left + 1) + left];
    }
};

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
矩阵乘法是计算机科学中非常基础的一种算法,它在图像处理、人工智能等领域都有广泛的应用。而分治法是一种常见的算法思想,它可以将一个问题分成多个子问题,再将子问题的结果合并起来得到最终结果。本文将介绍如何使用分治法实现矩阵乘法。 首先,我们来回顾一下矩阵乘法的定义。对于矩阵A和B,它们的乘积C的第i行第j列的元素可以表示为: C[i][j] = sum(A[i][k] * B[k][j]), k = 1,2,...,n 其中n为矩阵的大小。 接下来,我们将使用分治法来实现矩阵乘法。具体思路如下: 1.将矩阵A和B分别划分成4个子矩阵,即A11、A12、A21、A22和B11、B12、B21、B22。 2.递归地计算子矩阵的乘积,得到C11、C12、C21和C22。 3.将C11、C12、C21和C22合并成一个大的矩阵C。 下面是Python代码实现: ```python def matrix_multiply(A, B): # 判断矩阵大小是否相等 assert len(A[0]) == len(B) # 矩阵大小为1x1的情况 if len(A) == 1 and len(A[0]) == 1 and len(B) == 1 and len(B[0]) == 1: return [[A[0][0] * B[0][0]]] # 将矩阵A和B分成4个子矩阵 A11, A12, A21, A22 = split_matrix(A) B11, B12, B21, B22 = split_matrix(B) # 递归地计算子矩阵的乘积 C11 = matrix_add(matrix_multiply(A11, B11), matrix_multiply(A12, B21)) C12 = matrix_add(matrix_multiply(A11, B12), matrix_multiply(A12, B22)) C21 = matrix_add(matrix_multiply(A21, B11), matrix_multiply(A22, B21)) C22 = matrix_add(matrix_multiply(A21, B12), matrix_multiply(A22, B22)) # 合并C11、C12、C21和C22成一个大的矩阵C return merge_matrix(C11, C12, C21, C22) def split_matrix(matrix): # 将矩阵按行、列均分为两个子矩阵 n = len(matrix) m = len(matrix[0]) A = [[matrix[i][j] for j in range(m // 2)] for i in range(n // 2)] B = [[matrix[i][j] for j in range(m // 2, m)] for i in range(n // 2)] C = [[matrix[i][j] for j in range(m // 2)] for i in range(n // 2, n)] D = [[matrix[i][j] for j in range(m // 2, m)] for i in range(n // 2, n)] return A, B, C, D def merge_matrix(A, B, C, D): # 将四个子矩阵合并成一个大的矩阵 n = len(A) + len(C) m = len(A[0]) + len(B[0]) matrix = [[0] * m for i in range(n)] for i in range(len(A)): for j in range(len(A[0])): matrix[i][j] = A[i][j] for i in range(len(C)): for j in range(len(C[0])): matrix[i + len(A)][j] = C[i][j] for i in range(len(B)): for j in range(len(B[0])): matrix[i][j + len(A[0])] = B[i][j] for i in range(len(D)): for j in range(len(D[0])): matrix[i + len(A)][j + len(A[0])] = D[i][j] return matrix def matrix_add(A, B): # 矩阵加法 n = len(A) m = len(A[0]) matrix = [[0] * m for i in range(n)] for i in range(n): for j in range(m): matrix[i][j] = A[i][j] + B[i][j] return matrix ``` 可以使用以下代码进行测试: ```python A = [[1, 2], [3, 4]] B = [[5, 6], [7, 8]] C = matrix_multiply(A, B) print(C) # [[19, 22], [43, 50]] ``` 上面的代码实现了分治法实现矩阵乘法的基本思路,但是它的时间复杂度依然是O(n^3),因为我们在合并子问题的结果时需要遍历整个矩阵。实际上,我们可以在递归计算子问题时将子矩阵的结果直接传递到合并函数中,这样可以避免重复计算,从而将时间复杂度优化到O(n^2.81)。感兴趣的读者可以自行了解 Strassen 算法的实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清风玉骨

爱了!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值