打印数组中出现超过N/K的数字(复杂度O(n*k) 空间复杂度O(k))

剑指Offer39 数组中出现次数超过一半的数字
本文介绍了一种解决数组中寻找出现次数超过一半的数字的问题的方法,通过使用桶(hash)来跟踪候选者,特别针对k=2的情况。文章详细解释了算法的实现过程,包括如何维护桶内的候选者数量,以及最终确定结果的步骤。

先看一到入门题,这里k=2

剑指 Offer 39. 数组中出现次数超过一半的数字

难度简单34

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。

 

你可以假设数组是非空的,并且给定的数组总是存在多数元素。

 

示例 1:

输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
输出: 2

解题思路:

对于一般的k=2,我们都知道需要有一个候选人,其实k>2我们只需要k-1个候选人即可。所以我们可以用k个桶做个hash,存放这k-1个候选人,桶容量够我们就放新的人进去,桶满了要插新的人的时候,我们就对所有的key-1. key == 0时候我们清掉这个key.

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        int n =nums.size();
        int k = 2;  //对于任意k 修改这里即可 剑指offer这里为k=2
        int bucket = k-1;
        map<int,int> mm;
        for(auto it:nums){
            if(mm.size()<k){mm[it]++;}
            else{
                vector<int> mv;
                for(auto it2:mm){
                    mm[it2.first]--;
                    if(mm[it2.first]==0)mv.push_back(it2.first);
                }
                for(auto it2:mv)mm.erase(it2);
                if(mm.size()<k)mm[it]++;
            }
        }
        vector<int> ret;
        for(auto it:mm){
            int no = it.first;
            int cnt=0;
            for(int i= 0;i<nums.size();i++)if(nums[i] == it.first)cnt++;
            if(cnt>n/k)ret.push_back(it.first);
        }
        assert(ret.size());
        return ret[0];  //对于这道题返回的是第一个元素,对于一般的k返回ret
    }
};
#include<iostream> #include<string.h> #define MAXSIZE 100 using namespace std; typedef struct {//哈夫曼树结点的形式 int weight; //结点的权值 int parent,lchild,rchild; //结点的双亲、左孩子、右孩子的下标 }HTNode,*HuffmanTree; //动态分配数组存储哈夫曼树 typedef char **HuffmanCode; //定义编码表类型 int Search(char a[],char ch) {//查找数组中字符ch所在的位置,返回数组下标,否则返回-1 for(int i=0;a[i]!='\0';i++) { if(a[i]==ch) return i; } return -1; } void Sort(char a[],int b[],int len) {//按ASCII码冒泡排序 /**************begin************/ /**************end************/ } void Select_min(HuffmanTree HT,int n,int &s1,int &s2) {// 在HT[k](1≤k≤i-1)中选择两个其双亲域为0且权值最小的结点,并返回它们在HT中的序号s1和s2 /**************begin************/ /**************end************/ } int m; void CreateHuffmanTree(HuffmanTree &HT,int n,int b[]) {//构造哈夫曼树HT /**************begin************/ /**************end************/ } void CreateHuffmanCode(HuffmanTree HT,HuffmanCode &HC,int n) {//从叶子到根逆向求每个字符的哈夫曼编码,存储在编码表HC中 /**************begin************/ /**************end************/ } void CharFrequency(char ch[],char a[],int b[],int &j) {//统计词频 /**************begin************/ /**************end************/ } void PrintHT(HuffmanTree HT) {//输出哈夫曼树的存储结构的终态 /**************begin************/ /**************end************/ } void PrintHC(HuffmanCode HC,char a[],int j) {//输出每个字符的哈夫曼编码 /**************begin************/ /**************end************/ } int main() { char ch[MAXSIZE]; int i,j; while(cin>>ch) { if(ch[0]=='0') break; HuffmanTree HT; char a[MAXSIZE]={'\0'}; int b[MAXSIZE]={0}; j=0; //j统计不同字符的数量 CharFrequency(ch,a,b,j); //统计词频 Sort(a,b,j); //按ASCII码冒泡排序 for(i=0;a[i]!='\0';i++) //输出统计出来的字符和出现频率 { if(a[i+1]!='\0') cout<<a[i]<<":"<<b[i]<<" "; else cout<<a[i]<<":"<<b[i]<<endl; } //构造哈夫曼树 CreateHuffmanTree(HT,i,b); //构造哈夫曼树HT PrintHT(HT); //输出哈夫曼树的存储结构的终态 //哈夫曼编码 HuffmanCode HC; //编码表HC CreateHuffmanCode(HT,HC,j); PrintHC(HC,a,j); //输出每个字符的哈夫曼编码 int k; for(i=0;ch[i]!='\0';i++) //输出编码后的字符串 { for(k=0;k<j;k++) { if(ch[i]==a[k]) cout<<HC[k+1]; } } cout<<endl; cout<<ch<<endl;//输出解码后的字符串(与输入的字符串相同) } return 0; }补全·代码
最新发布
11-26
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值