基础数字(一)位运算 哈希(数组中元素出现次数)

目录

力扣剑指 Offer II 070. 排序数组中只出现一次的数字

数组中只出现一次的数(其它数出现k次)_牛客题霸

数组中只出现一次的两个数字_牛客题霸_牛客网

 数组中出现次数超过一半的数字_牛客题霸_牛客网

 缺失的第一个正整数_牛客题霸_牛客网


力扣剑指 Offer II 070. 排序数组中只出现一次的数字

给定一个只包含整数的有序数组 nums ,每个元素都会出现两次,唯有一个数只会出现一次,请找出这个唯一的数字。

你设计的解决方案必须满足 O(log n) 时间复杂度和 O(1) 空间复杂度。

【解法一】前后一起比较

class Solution {
public:
    int singleNonDuplicate(vector<int>& nums) {
        if(nums.size()==1) return nums[0];
        if(nums[0]!=nums[1]) return nums[0];
        for(int i=0;i<nums.size();){
            if(nums[i]!=nums[i+1]) return nums[i];
            i+=2;
        }
        return -1;
    }
};

【解法二】直接就是一个异或

class Solution {
public:
    int singleNonDuplicate(vector<int>& nums) {
        int res = 0;
        for(auto e : nums)
            res^=e;
        return res;
    }
};

 【解法三】二分法

class Solution {
public:
    int singleNonDuplicate(vector<int>& nums) {
        int left = 0;
        int right = nums.size()-1;
        while(left<right)
        {
            int mid = (left+right)>>1;
            if(nums[mid] == nums[mid^1])
                left = mid+1;
            else
                right = mid;
        }
        return nums[left];
    }
};

数组中只出现一次的数(其它数出现k次)_牛客题霸

给定一个长度为 n 的整型数组 arr 和一个整数 k(k>1) 。

已知 arr 中只有 1 个数出现一次,其他的数都出现 k 次。

请返回只出现了 1 次

数。

【解法一】排序之后进行逐k进行遍历


class Solution {
public:
    int foundOnceNumber(vector<int>& arr, int k) {
        // write code here
        sort(arr.begin(), arr.end());
        for(int i = 0; i < arr.size()-1; i += k)
        {
            if(arr[i] != arr[i+1])
                return arr[i];
        }
        return arr[arr.size()-1];
    }
};

【解法二】使用哈希遍历一遍然后查找值为1的数


class Solution {
public:
    int foundOnceNumber(vector<int>& arr, int k) {
        // write code here
        map<int,int>mp;
        for(auto e : arr)
            mp[e]++;
        for(auto e : arr)
            if(mp[e] == 1)
                return e;
        return -1;
    }
};

数组中只出现一次的两个数字_牛客题霸_牛客网

一个整型数组里除了两个数字只出现一次,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。

数据范围:数组长度 2≤n≤10002≤n≤1000,数组中每个数的大小 0<val≤10000000<val≤1000000
要求:空间复杂度 O(1)O(1),时间复杂度 O(n)O(n)

【解法一】使用哈希遍历    注意运用mp接口的使用

class Solution {
public:
    vector<int> FindNumsAppearOnce(vector<int>& array) {
        // write code here
        map<int, int>mp;
        for(auto e : array)
        {
            mp[e]++;
        }
        vector<int> res;
        for(auto it = mp.begin(); it!=mp.end(); it++)
        {
            if(it->second == 1)
                res.push_back(it->first);
        }
        if(res[0]>res[1])
        swap(res[0], res[1]);
        return res;
    }
};

【解法二】使用异或运算

 注意点  异或操作 0 XOR a = a   a XOR a = 0

从第一个数开始俩俩之间进行异或操作,如果后一个数与前一个异或后的数不相等 只有俩种情况,一种是前面是俩相同的数,异或之后结果为0,0与第i个数不相同,这种只需要继续进行异或即可,还有一种是遇到了前后俩个数不相同情况,那么就是找到了,把当前i指向的数放入res数组中即可。找到一个后重新开始,将x重新初始为0,继续进行如此操作

class Solution {
public:
    vector<int> FindNumsAppearOnce(vector<int>& array) {
        // write code here
        sort(array.begin(), array.end());
        vector<int> res;
        int x = 0;
        for(int i = 0; i < array.size()-1; i++)
        {
            x ^= array[i];
            if(array[i+1]!=x && x!=0)
            {
                res.push_back(array[i]);
                x = 0;
            }
        }
        if(res.size()==1)res.push_back(array.back());
        return res;
    }
};

 数组中出现次数超过一半的数字_牛客题霸_牛客网

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

例如输入一个长度为9的数组[1,2,3,2,2,2,5,4,2]。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。

数据范围:n≤50000n≤50000,数组中元素的值 0≤val≤100000≤val≤10000

要求:空间复杂度:O(1)O(1),时间复杂度 O(n)O(n)

【解法一】排序取中

class Solution {
public:
    int MoreThanHalfNum_Solution(vector<int> numbers) {
        sort(numbers.begin(), numbers.end());
        return numbers[numbers.size() / 2];
    }
};

【解法二】哈希表

class Solution {
public:
    int MoreThanHalfNum_Solution(vector<int> numbers) {
        map<int, int> mp;
        int n = numbers.size();
        for(auto e : numbers)
        {
            mp[e]++;
            if(mp[e] > n/2)
                return e;
        }
        return 0;
    }
};

 缺失的第一个正整数_牛客题霸_牛客网

给定一个无重复元素的整数数组nums,请你找出其中没有出现的最小的正整数

进阶: 空间复杂度 O(1)O(1),时间复杂度 O(n)O(n)

数据范围:

−231≤nums[i]≤231−1−231≤nums[i]≤231−1

0≤len(nums)≤5∗1050≤len(nums)≤5∗105

【解法一】暴力查找(找之前排序一下哦 不然会超时 嘻嘻嘻)

class Solution {
public:
    int minNumberDisappeared(vector<int>& nums) {
        // write code here
        sort(nums.begin(), nums.end());
        int i = 1;
        while(1)
        {
            if(find(nums.begin(),nums.end(),i++)==nums.end())
            {
                return i-1;
            }
        }
        return 0;
    }
};

【解法二】哈希 跟我的方法一差不多诶,不过人家哈希表的find时间复杂度为O(1)慕了慕了

class Solution {
public:
    int minNumberDisappeared(vector<int>& nums) {
        // write code here
        map<int, int>mp;
        for(auto e : nums)
            mp[e]++;
        int res = 1;
        while(mp.find(res) != mp.end())
            res++;
        return res;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值