无序数组找中位数_无序数组的中位数-程序员宅基地

技术标签: 算法题  基础知识  

1.无序数组找中位数

  1. 思路一
    把无序数组排好序,取出中间的元素
    时间复杂度 采用普通的比较排序法 O(N*logN)
    如果采用非比较的计数排序等方法, 时间复杂度 O(N), 空间复杂度也是O(N).

  2. 思路二
    (1)将前(n+1)/2个元素调整为一个小顶堆
    (2)对后续的每一个元素,和堆顶比较,如果小于等于堆顶,丢弃之,取下一个元素。 如果大于堆顶,用该元素取代堆顶,调整堆,取下一元素。重复2.2步
    (3)当遍历完所有元素之后,堆顶即是中位数。
    注:如果数组元素的个数是奇数,取数组前(size+1)/2个元素建堆,如果是偶数则取前 size/2 个元素建堆。但如果是数据流,数据个数是动态变动的,则应采用小根堆+大根堆的办法,具体见本文第5点介绍。

  3. 思路三
    找中位数也可以用快排分治的思想。具体如下:
    (1)任意挑一个元素,以改元素为支点,划分集合为两部分,如果左侧集合长度恰为 (n-1)/2,那么支点恰为中位数。如果左侧长度<(n-1)/2, 那么中位点在右侧,反之,中位数在左侧。
    (2)进入相应的一侧继续寻找中位点。
    注:可参考快排思想实现Top K

拓展:查找N个元素中的第K个小的元素,假设内存受限,仅能容下K/4个元素
分趟查找:

  1. 第一趟,用堆方法查找最小的K/4个小的元素,同时记录剩下的N-K/4个元素到外部文件。
  2. 第二趟,用堆方法从第一趟筛选出的N-K/4个元素中查找K/4个小的元素,同时记录剩下的N-K/2个元素到外部文件。
  3. 第四趟,用堆方法从第一趟筛选出的N-K/3个元素中查找K/4个小的元素,这是的第K/4小的元素即使所求。

https://blog.csdn.net/zdl1016/article/details/4676882


2.将十进制数字转化为X 进制的字符串

//将十进制数转化为X进制字符串 
string trans(int num, int base){
    
	string str;
	while(num > 0){
    
		if(num % base < 10)
			str += num % base + '0';
		else
			str += num % base - 10 + 'A';
		num = num / base;
	}
	reverse(str.begin(),str.end());
	
	return str;
}

3.找出字符串中第k次出现的字符

  1. 思路一
    遍历这个字符串(缺点是要对这个字符串查找好多次)
  2. 思路二
    (1) 先创建一个数组然后这个数组你就放成256个元素。
    (2) 把这个字符串转化成ASCLL码进行查找。(因为ASCLL码的范围比较小)
    (3) 当我们发现字符串中出现a(a的ASCLL为97)的时候,我们可以把刚才256个元素中下边为97的元素的值加一。
char find_first_K(string str, int K)
{
    
	int count[256] = {
     0 };
	for (char ch : str) ++count[ch];

	for (char ch : str) {
    
		if (count[ch] == K)
			return ch;
	}

	return '0';
}

5.找出数据流中的中位数

在这里插入图片描述

注意:始终保证小根堆A中元素个数不少于大根堆B中的元素个数,即A、B元素相等时,将B中最大元素加入A,否则将A中最小元素加入B,来维持元素个数平衡。

class MedianFinder {
    
private:
    priority_queue<int,vector<int>, greater<int>> A;    //小根堆
    priority_queue<int,vector<int>, less<int>> B;       //大根堆

public:
    //插入新元素
    void addNum(int num) {
    
        if(A.size()==B.size()){
     //把B中最大元素加入到A
            B.push(num);
            A.push(B.top());
            B.pop();
        }else{
                      //把A中最小元素加入到B
            A.push(num);
            B.push(A.top());
            A.pop();
        }
    }
    
    //查找当前中位数
    int findMedian() {
    
        return A.size()==B.size()?(A.top()+B.top())/2.0:A.top();
    }
};

6.英文字符串流和中文字符串流如何分词

一种对英文字符串进行分词的方法:https://d.wanfangdata.com.cn/periodical/jsjyyyj200707016

字典与统计相结合的中文分词方法:https://d.wanfangdata.com.cn/periodical/xxwxjsjxt200609039

暴力方法:

  1. 英文分词:根据字符串中的空格、标点符号进行分词。
  2. 中文分词:固定两个字为一词进行拆分。

7.10亿QQ号去重

1. 内存够的情况

分段、map、多线程。

  1. 分段:哈希分桶,根据哈希值对桶数目取模得到对应桶号。
  2. map:需要计数采用unordered_map去重;不需要计数采用set去重。
  3. 多线程:将数据进行哈希分桶之后,各桶内map的去重可以采用多线程执行。

2. 内存不够的情况

思路一:bitmap

位图bitmap:每个int数字只用一个比特位来做标记

位图的操作(算法)基本依赖于下面3个元操作:

set_bit(char x, int n); //将x的第n位置1,可以通过x |= (1 << n)来实现

clr_bit(char x, int n); //将x的第n位清0,可以通过x &= ~(1 << n)来实现

get_bit(char x, int n); //取出x的第n位的值,可以通过(x >> n) & 1来实现

比如,要对数字int x = 1848105做标记,就可以调用set_bit(bit_map[x/8], x%8);

除法看做求“组编号”,x/8即是 以8个位为一个小组,分组到编号为idx = x/8的bit_map元素中,然后在组内偏移lft = x%8个比特位。

10亿数字(int 32位):10^8 * 32 / 8 = 40亿字节 / 1024 ≈ 400万 KB / 1024 ≈ 4000 MB / 1024 ≈ 4 GB
int 32位所需bitmap大小:2^32 / 8 = 2^29 字节 / 1024 = 2^19 KB / 1024 = 2^9 MB = 512 MB

10亿数字(long long 64位):4 GB * 2 = 8GB
long long 64位所需bitmap大小:2^64 / 2^23 = 2^41 MB / 1024 = 2^31 GB / 1024 = 2^21 TB / 1024 = 2048 PB = 2 EB

https://www.cnblogs.com/zhanghaiba/p/3594559.html

思路二:多路归并排序

问题:如何给100亿个数字排序?

注:100亿个 int 型数字放在文件里面大概有 37.2GB

  1. 把这个37GB的大文件,用哈希分成1000个小文件,每个小文件平均38MB左右(理想情况),把100亿个数字对1000取模,模出来的结果在0到999之间,每个结果对应一个文件,所以我这里取的哈希函数是 h = x % 1000,哈希函数取得”好”,能使冲突减小,结果分布均匀。
  2. 按各输入文件中下一个读到的元素的大小构造一个输入流最小堆.
  3. 从堆顶文件里读一个元素并写入输出文件.
  4. 同时按读的那个文件的下一个元素的值调整堆.
  5. 若第3步已到达文件结尾.则从堆中删除该输入流.
  6. 如果堆中还有元素. 回到第2步.

3. 外存不够的情况

考虑是不是可以进行分布式处理

待查~


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_43202635/article/details/115425414

智能推荐

关于Keil中“ Error: L6200E: Symbol xxx multiply defined ”的报错解决办法_..\..\output\projects.axf: error: l6200e: symbol o-程序员宅基地

文章浏览阅读4.8k次,点赞9次,收藏7次。然后我把#include "oledfont.h" 的编译位置放在了 oled.h的头文件中,如果要把这个错误改正,只需要把#include "oledfont.h"的编译位置放在 oled.c中。_..\..\output\projects.axf: error: l6200e: symbol oled_f8x16 multiply defined

LTP 依存句法分析_tone分析进行ltp句法分析时需要head词还是dependent词-程序员宅基地

文章浏览阅读1.1w次,点赞6次,收藏46次。 依存句法依存语法 (Dependency Parsing, DP) 通过分析语言单位内成分之间的依存关系揭示其句法结构。 直观来讲,依存句法分析识别句子中的“主谓宾”、“定状补”这些语法成分,并分析各成分之间的关系。#依存句法分析模型parser = Parser()parser.load(os.path.join(MODELDIR, "parser.model"))arcs..._tone分析进行ltp句法分析时需要head词还是dependent词

Moscow Pre-Finals Workshop 2020 - Legilimens+Coffee Chicken Contest (XX Open Cup, Grand Prix of Nanj-程序员宅基地

文章浏览阅读587次。J.Gaokao题意:一个三角,第一个和最后一个数是1,其他位置的数是头上两个数之和。问第K行有多少奇数。思路:遍历,判断奇数数目。#include <bits/stdc++.h> using namespace std; int main(){ long long x; int t; cin >> t; while(t -- ) { cin >> x; if(x <= _moscow pre-finals workshop 2020 - legilimens+coffee chicken contest (xx open

1147: 查找子数组 C语言_题目描述 小c学习数组时非常喜欢取子数组这一操作,即选择-一个起始点一个终止点,-程序员宅基地

文章浏览阅读729次。1147: 查找子数组时间限制: 1 Sec 内存限制: 128 MB提交: 5264 解决: 3275[状态] [讨论版] [提交] [命题人:admin]题目描述给定两个整型数组,数组a有n个元素, 数组b有m个元素,1<=m<=n<100,请检验数组b是否是数组a的子数组。若从数组a的某个元素a[i]开始,有b[0]=a[i],b[1]=a[i+1],…,b[m]=a[i+m],则称数组b是数组a的子数组。输入输入第一行为两个整数n和m;第二行为数组a的n个整数;第_题目描述 小c学习数组时非常喜欢取子数组这一操作,即选择-一个起始点一个终止点,

公司企业展示门户店铺展示宣传微信小程序前端源码_广告公司小程序源码-程序员宅基地

文章浏览阅读805次,点赞2次,收藏11次。微信小程序也是这么多年来中国IT行业里一个真正能够影响到普通程序员的创新成果,已经有超过150万的开发者加入到了微信小程序的开发,与我们一起共同发力推动微信小程序的发展,微信小程序应用数量超过了一百万,覆盖200多个细分的行业,日活用户达到两个亿,微信小程序还在许多城市实现了支持地铁、公交服务。微信小程序,小程序的一种,英文名Wechat Mini Program,是一种不需要下载安装即可使用的应用,它实现了应用“触手可及”的梦想,用户扫一扫或搜一下即可打开应用。对话框发送:wx门户。_广告公司小程序源码

angular ng-template 灵活运用_angular双重嵌套表单动态项-程序员宅基地

文章浏览阅读6k次。用处可以随意调整组件显示的位置,个人觉得在嵌套组件中最方便举例app.component.tsimport { Component, ViewChild, TemplateRef,ViewContainerRef } from '@angular/core';@Component({ selector: 'app-root', styleUrls: ['./app.compone..._angular双重嵌套表单动态项

随便推点

spring-prometheus的指标含义_http_server_requests_seconds_sum-程序员宅基地

文章浏览阅读8.1k次。前言spring-boot作为一个长时间运行的服务,需要也应该能采集到一些指标来反映系统自身的运行状态。下面就spring-boot输出的一些指标分类说明。依赖spring-boot开启指标采集需要加入prometheus依赖。指标处理nametypedatahttp_server_requests_secondssummaryhttp_server_requests_seconds_count{exception=“None”,method=“GET”,outcome=_http_server_requests_seconds_sum

[putty]设置默认编码_putty设置默认编码重新打开也生效-程序员宅基地

文章浏览阅读5.8k次。putty是个很好的连接linux的客户端工具,但是用putty时,时常出现乱码问题,这时候需要在Translation中设置一下。但是每次连接都要设就非常麻烦了,这时候,可以在保存session的时候,先设好,以后从保存list中进入,这样就不需要手动设编码了。_putty设置默认编码重新打开也生效

HTML接收前一个页面的传值并将他传递个下一个页面不发生跳转_原生htmk上一次页面的内容代到下一个页面-程序员宅基地

文章浏览阅读1.7k次。最近公司要做BPM流程管理,用到了Ultimus,然后在审批页面要嵌入流程图和审批记录步骤页面,而这两个页面需要传相关参数,这个参数则是前一个页面传过来的。这个问题开始困扰着我,HTML传来传去,后来发现这个问题原来如此简单。。 审批记录

MFC程序中如何接受命令行参数_mfc程序接收参数方式-程序员宅基地

文章浏览阅读8.4k次,点赞3次,收藏10次。在MFC程序中,可以用以下几种方法来获取命令行参数。 为方便说明,我们假设执行了命令:C:\test\app.exe -1 -2 方法一 ::GetCommandLine(); 将获取到 "C:\test\app.exe" -1 -2 方法二 for (int i=0;i__argv[i]; 将依次得到C:\test\app.exe -1 -2 } 方法_mfc程序接收参数方式

未能加载文件或程序集"Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad_未能加载文件或程序集“microsoft.web.infrastructure, version=1-程序员宅基地

文章浏览阅读4.4w次,点赞3次,收藏2次。打开vs2010,工具,扩展管理器,然后点击在线,安装_未能加载文件或程序集“microsoft.web.infrastructure, version=1.0.0.0, culture

编译原理 第十章 代码优化_编译原理 名词解释 代码优化-程序员宅基地

文章浏览阅读680次,点赞3次,收藏4次。第十章 代码优化优化:指对程序进行等价变换,使得从变换后的程序出发,能生成更有效的目标代码。前端优化:在目标代码生成以前,对语法分析后的目标代码进行优化后端优化:在生成目标代码时进行优化,依赖于具体的计算机指令系统10.1 概述优化原则:等价原则:经过优化的代码不应改变程序运行的结果有效原则: 有效原则:使优化后所产生的目标代码运行时间较短,占用的存储空间较小合算原则:应尽可能以较低的代价取得较好的优化效果10.2局部优化10.2.1 基本块和流图基本块:指程序中一段顺序执_编译原理 名词解释 代码优化