算法题:数组中出现数字个数总结

  1. 找出数组中出现次数超过一半的数字(剑指offer29 leetcode169
    思路:1)partition,快排的部分功能,O(n)。出现次数超过一半即可用快排的思想求中位数即可。
    2)根据数组的特点出发,保存一个数和一个次数,如果下次遇到的数与保存的数相同,次数加一,不同减一,次数为0 则保存下一个数,并把次数设为1.
class Solution {
public:
    int majorityElement(vector<int>& nums) {
        int num,count=0;
        for(int i=0;i<nums.size();i++){
            if(count==0)
                num=nums[i];
            if(nums[i]==num)
                count++;
            else
                count--;
        }
        return num;
    }
};
  1. 找出最小的k个数(topK)
    1.将输入内容进行完全排序,选出排在前k的元素,可选择快速排序,堆排序和归并排序,时间复杂度O(nlogn)。
    2.只对前K大的元素进行排序,可选择冒泡排序或选择排序进行处理,即每次冒泡都能找到所求的一个元素,时间复杂度O(Kn)。
    3.对输入内容不进行排序:1)利用最小堆维护大小为K的数组,该小根堆中的元素是排名前K的数,其中根是最小的数。此后,每次从原数组中取一个元素与根进行比较,如大于根的元素,则将根元素替换并进行堆调整(下沉),即保证小根堆中的元素仍然是排名前K的数,且根元素仍然最小;否则不予处理,取下一个数组元素继续该过程。该算法的时间复杂度是O(nlogK)。特点:不需要一次将原数组中的内容全部加载到内存中。2)利用快排的分划函数找到划分位置k,时间复杂度O(n)。(只有当我们可以修改输入的数组时可用)
  2. 第一个只出现一次的字符(剑指offer35,leetcode387
    思路:1)排序,O(nlogn)
    2)哈希表,第一遍扫描,用哈希表存储字符出现的个数;第二遍扫描,找出第一个个数为1的字符,O(n)
class Solution {
public:
    int firstUniqChar(string s) {
        unordered_map<char,int> map;
        for(int i=0;i<s.size();i++){
            map[s[i]]+=1;
        }
        for(int i=0;i<s.size();i++){
            if(map[s[i]]==1)
                return i;
        }
        return -1;
    }
};
  1. 字符流中第一个不重复的字符(剑指offer269,[nowcoder]
    思路同上,如需存储位置,则将map中的value替换为位置,出现两次及以上赋值为-2,初始化为-1.
    (https://www.nowcoder.com/questionTerminal/00de97733b8e4f97a3fb5c680ee10720))
class Solution
{
public:
  //Insert one char from stringstream
    void Insert(char ch)
    {
         s+=ch;
         map[ch]+=1;
    }
  //return the first appearence once char in current stringstream
    char FirstAppearingOnce()
    {
        for(int i=0;i<s.size();i++){
            if(map[s[i]]==1)
                return s[i];
        }
        return '#';
    }
    unordered_map<char,int> map;
    string s="";
};
  1. 整数数组中,第一个没有出现的正整数leetcode41
    思路:考虑整数的范围和数组的长度n的关系,第一个没有出现的正整数肯定小于等于长度。
    (交换可用algorithm.h里的swap)
class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        int n=nums.size();
        if(n==0) return 1;
        for(int i=0;i<n;){
            if(nums[i]<n+1&&nums[i]>0&&nums[i]!=nums[nums[i]-1]){
                int tmp=nums[i];
                nums[i]=nums[tmp-1];
                nums[tmp-1]=tmp;
            }
            else
                i++;
        }
        for(int i=0;i<n;i++){
            if(nums[i]!=i+1)
                return i+1;
        }
        return n+1;
    }
};
  1. 找出数组中只出现一次的数字,其它数字都出现了两次
    异或
class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int result=0;
        for(int i=0;i<nums.size();i++){
            result=result^nums[i];
        }
        return result;
    }
};
  1. 找出数组中只出现一次的数字,其它数字都出现了三次。
    思路:1)使用map,增加了空间复杂度O(n)。2)排序,时间复杂度O(nlogn)
    3)位操作思想,不管非孤异元素重复多少次,这是通用做法。
    对于右数第i位,如果孤异元素该位为0,则该位为1的元素总数为3的整数倍。
    如果孤异元素该位为1,则该位为1的元素总数不为3的整数倍(也就是余1)。
    换句话说,如果第i位为1的元素总数不为3的整数倍,则孤异数的第i位为1,否则为0.
    (如果非孤异元素重复n次,则判断是否为n的整数倍)
class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int n=nums.size();
        int result=0;
        for(int i=0;i<32;i++){
            int count=0;
            int mask=1<<i;
            for(int j=0;j<n;j++){
                if(nums[j]&mask)
                    count++;
            }
            if(count%3)
                result|=mask;
        }
        return result;
    }
};

http://blog.csdn.net/jeanphorn/article/details/46501331

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容

  • 概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    蚁前阅读 5,167评论 0 52
  • 概述:排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    每天刷两次牙阅读 3,727评论 0 15
  • 1 序 2016年6月25日夜,帝都,天下着大雨,拖着行李箱和同学在校门口照了最后一张合照,搬离寝室打车去了提前租...
    RichardJieChen阅读 5,076评论 0 12
  • 概述排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的...
    Luc_阅读 2,255评论 0 35
  • 元宝,我亲爱的儿子,看着你一天天长大,我的心就像鲜花在一天天绽放,我期待你的成长,你的变化……可是,我又害怕你的成...
    莫到花开阅读 297评论 0 0