c++ 给定一个非常巨大的数组,如何找到它的中值

快速选择算法(最优解) 

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class Solution {
private:
    // 快速选择算法中的分区函数
    int partition(vector<int>& nums, int left, int right) {
        int pivot = nums[right]; // 选择最右边的元素作为枢纽元
        int i = left - 1; // i 指向小于等于 pivot 的元素
        for (int j = left; j < right; j++) {
            if (nums[j] <= pivot) {
                i++;
                swap(nums[i], nums[j]); // 将小于等于 pivot 的元素交换到左侧
            }
        }
        swap(nums[i + 1], nums[right]); // 将 pivot 放到正确的位置
        return i + 1; // 返回 pivot 的索引
    }

    // 快速选择算法
    int quickSelect(vector<int>& nums, int left, int right, int k) {
        if (left == right) return nums[left]; // 只有一个元素,直接返回

        int pivotIndex = partition(nums, left, right); // 获取 pivot 的索引
        if (k == pivotIndex) {
            return nums[k]; // 找到第 k 个最大元素
        } else if (k < pivotIndex) {
            return quickSelect(nums, left, pivotIndex - 1, k); // 在左侧继续查找
        } else {
            return quickSelect(nums, pivotIndex + 1, right, k); // 在右侧继续查找
        }
    }

public:
    double findMedian(vector<int>& nums) {
        int n = nums.size();
        if (n % 2 == 1) {
            return quickSelect(nums, 0, n - 1, n / 2); // 奇数个元素,直接找到中位数
        } else {
            int left = quickSelect(nums, 0, n - 1, n / 2 - 1); // 找到第 n/2-1 个最大元素
            int right = quickSelect(nums, 0, n - 1, n / 2); // 找到第 n/2 个最大元素
            return (left + right) / 2.0; // 计算中位数
        }
    }
};

int main() {
    vector<int> nums = {3, 2, 1, 5, 6, 4};
    Solution sol;
    double median = sol.findMedian(nums);
    cout << "中位数是:" << median << endl;
    return 0;
}

 如果数组太大,无法一次性加载到内存中,或者我们不能修改原数组,可以考虑使用基于分块的近似算法:

基于分块的近似算法(适用于超大数据集)

class Solution {
public:
    double findApproximateMedian(const vector<int>& nums) {
        const int BUCKET_SIZE = 1000;  // 可以根据实际情况调整
        vector<int> count(BUCKET_SIZE, 0);
        int minVal = INT_MAX, maxVal = INT_MIN;
        
        // 第一次遍历:找到最小值和最大值
        for (int num : nums) {
            minVal = min(minVal, num);
            maxVal = max(maxVal, num);
        }
        
        double bucketSize = (maxVal - minVal + 1.0) / BUCKET_SIZE;
        
        // 第二次遍历:统计每个桶的元素数量
        for (int num : nums) {
            int index = min((int)((num - minVal) / bucketSize), BUCKET_SIZE - 1);
            count[index]++;
        }
        
        // 找到中位数所在的桶
        int medianCount = (nums.size() + 1) / 2;
        int bucketIndex = 0;
        int sum = 0;
        while (sum < medianCount) {
            sum += count[bucketIndex];
            bucketIndex++;
        }
        bucketIndex--;
        
        // 计算近似中位数
        double medianLow = minVal + bucketIndex * bucketSize;
        double medianHigh = minVal + (bucketIndex + 1) * bucketSize;
        return (medianLow + medianHigh) / 2.0;
    }
};

这个算法的优点:

  1. 只需要两次遍历数组。
  2. 空间复杂度是O(1),因为使用了固定大小的桶。
  3. 可以处理非常大的数据集,甚至是流数据。
  4. 不需要修改原数组。

缺点是结果是近似值,不是精确的中位数。精确度可以通过增加桶的数量来提高,但会增加空间复杂度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/758460.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

羊了个羊:羊、羊、羊

一、I am me&#xff0c;羊羊羊 英文中的 我就是我&#xff08;I am me&#xff09;&#xff0c;其实就是&#xff1a;羊 羊 羊&#xff0c;为什么会有这么一个结论呢&#xff1f; 请往下看&#xff1a; I&#xff0c;就是羊 am&#xff08;是&#xff09;&#xff0c;也是羊 …

『MySQL 实战 45 讲』22 - MySQL 有哪些“饮鸩止渴”提高性能的方法?

MySQL 有哪些“饮鸩止渴”提高性能的方法&#xff1f; 需求&#xff1a;业务高峰期&#xff0c;生产环境的 MySQL 压力太大&#xff0c;没法正常响应&#xff0c;需要短期内、临时性地提升一些性能 短连接风暴 短连接模式&#xff1a;执行很少的 SQL 语句就断开&#xff0c;…

等保测评练习卷15

等级保护初级测评师试题15 姓名&#xff1a; 成绩&#xff1a; 判断题&#xff08;10110分&#xff09; 1. 防火墙应关闭不需要的系统服务、默认共享和高危端口&#xff0c;可以有效降低系统遭受攻击的可能性。&am…

学会整理电脑,基于小白用户(无关硬件升级)

如果你不想进行硬件升级&#xff0c;就要学会进行整理维护电脑 基于小白用户&#xff0c;每一个操作点我都会在后续整理出流程&#xff0c;软件推荐会选择占用小且实用的软件 主要从三个角度去讨论【如果有新的内容我会随时修改&#xff0c;也希望有补充告诉我&#xff0c;我…

【数据结构】详解二叉树之堆

失败只是暂时停止成功&#xff0c;假如我不能&#xff0c;我就一定要&#xff1b;假如我要&#xff0c;我就一定能&#xff01;&#x1f493;&#x1f493;&#x1f493; 目录 ✨说在前面 &#x1f34b;知识点一&#xff1a;树的概念和结构 • &#x1f330;1.什么是树&#x…

什么是自然语言处理(NLP)?详细解读文本分类、情感分析和机器翻译的核心技术

什么是自然语言处理&#xff1f; 自然语言处理&#xff08;Natural Language Processing&#xff0c;简称NLP&#xff09;是人工智能的一个重要分支&#xff0c;旨在让计算机理解、解释和生成人类的自然语言。打个比方&#xff0c;你和Siri对话&#xff0c;或使用谷歌翻译翻译一…

h5兼容table ,如何实现h5在app内使用h5渲染table表格而且实现横屏预览?

压图地址 横屏div 通过css 实现 transform: rotate(90deg); transformOrigin: 50vw 50vw ; height: 100vw; width: 100vh;<divclass"popup-box":style"{transform: originSet 0 ? rotate(90deg) : ,transformOrigin: originSet 0 ? 50vw 50vw : ,height…

正版软件 | R-Studio T80+:数据恢复与取证分析的专业之选

在数据恢复和数字取证领域&#xff0c;专业人士需要一款强大、可靠的工具来应对复杂和高要求的任务。R-Studio T80 由 R-TT 公司推出的新型许可软件&#xff0c;以其年度付费订阅模式&#xff0c;为专家提供了成本效益更高的解决方案。 全面功能&#xff0c;专业服务 R-Studio …

如何在 Linux 中后台运行进程?

一、后台进程 在后台运行进程是 Linux 系统中的常见要求。在后台运行进程允许您在进程独立运行时继续使用终端或执行其他命令。这对于长时间运行的任务或当您想要同时执行多个命令时特别有用。 在深入研究各种方法之前&#xff0c;让我们先了解一下什么是后台进程。在 Linux 中…

秋招突击——6/28、6.29——复习{数位DP——度的数量}——新作{}

文章目录 引言复习数位DP——度的数量个人实现参考实现 总结 引言 头一次产生了那么强烈的动摇&#xff0c;对于未来没有任何的感觉的&#xff0c;不知道将会往哪里走&#xff0c;不知道怎么办。可能还是因为实习吧&#xff0c;再加上最近复习也没有什么进展&#xff0c;并不知…

AI助力校园安全:EasyCVR视频智能技术在校园欺凌中的应用

一、背景分析 近年来&#xff0c;各地深入开展中小学生欺凌行为治理工作&#xff0c;但有的地方学生欺凌事件仍时有发生&#xff0c;严重损害学生身心健康&#xff0c;引发社会广泛关注。为此&#xff0c;教育部制定了《防范中小学生欺凌专项治理行动工作方案》进一步防范和遏…

2,linux服务器使用学习

目录 服务器使用-SSH 介绍 使用 OpenSSH-Linux FinalShell-Windows 阿里云服务器使用示例 领取免费账号 进行登录 服务器使用-SSH 介绍 Secure Shell(SSH) 是由 IETF(The Internet Engineering Task Force) 制定的建立在应用层基础上的安全网络协议。它是专为远程登…

拆分盘投资策略解析:机制、案例与风险考量

一、引言 随着互联网技术的迅猛发展和金融市场的不断创新&#xff0c;拆分盘这一投资模式逐渐崭露头角&#xff0c;成为投资者关注的焦点。它基于特定的拆分策略&#xff0c;通过调整投资者持有的份额和单价&#xff0c;实现了看似稳健的资产增长。本文旨在深入探讨拆分盘的运…

Meven

目录 1.简介2.Maven项目目录结构2.1 约定目录结构的意义2.2 约定大于配置 3. POM.XML介绍3.2 依赖引用3.3 属性管理 4 Maven生命周期4.1 经常遇到的生命周期4.1 全部生命周期 5.依赖范围&#xff08;Scope&#xff09;6. 依赖传递6.1 依赖冲突6.2 解决依赖冲突6.2.1 最近依赖者…

【wsl2】升级wsl及ubuntu22.04

y9kp的wsl2 还是用的自己的子网 很久没用wsl2的ubutnu22.04系统 发现无法启动 等待了挺久&#xff0c;启动了 但同时我也在升级wsl中&#xff1a; 升级wsl wsl --update 这个升级是对ubuntu22.04的运行没影响。 apt-get update 然后upgrade wsl2的升级一直在90%多不动 然…

算法 —— 双指针

目录 移动零 复写零 快乐数 盛最多水的容器 有效三角形的个数 查找总价格为目标值的两个商品 三数之和 四数之和 移动零 下图以样例1为例&#xff0c;看下图如何做到保证非零元素相对顺序前提下&#xff0c;移动零元素。 代码实现如下&#xff1a; class Solution {…

数据结构—判断题

1.数据的逻辑结构说明数据元素之间的顺序关系&#xff0c;它依赖于计算机的存储结构。 答案&#xff1a;错误 2.(neuDS)在顺序表中逻辑上相邻的元素&#xff0c;其对应的物理位置也是相邻的。 答案&#xff1a;正确 3.若一个栈的输入序列为{1, 2, 3, 4, 5}&#xff0c;则不…

加密与安全_三种方式实现基于国密非对称加密算法的加解密和签名验签

文章目录 国际算法基础概念常见的加密算法及分类签名和验签基础概念常见的签名算法应用场景 国密算法对称加密&#xff08;DES/AES⇒SM4&#xff09;非对称加密&#xff08;RSA/ECC⇒SM2&#xff09;散列(摘要/哈希)算法&#xff08;MD5/SHA⇒SM3&#xff09; Code方式一 使用B…

3、Redis集群原理分析

槽定位 (Slot Mapping): Redis Cluster 将所有数据划分为 16384 个槽位&#xff08;slots&#xff09;&#xff0c;每个槽位由一个或多个节点负责管理。Redis 集群通过 CRC16 哈希算法来计算每个 key 的哈希值&#xff0c;并对 16384 取模以确定该 key 应该存储在哪个槽位上。…

Maven基础学习

一、Why? 1.真的需要吗? 2.究竟为什么? 二、What? 1.Maven简介 2.什么是构建 3.构建过程的几个主要环节 4.自动化构建 5.Maven核心概念 6.安装Maven 三、How? 四、约定的目录结构
最新文章