• 【LeetCode】【剑指offer】【数组中数字出现的次数(二)】


     剑指 Offer 56 - II. 数组中数字出现的次数 II

    在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。

    示例 1:

    输入:nums = [3,4,3,3]
    输出:4
    示例 2:

    输入:nums = [9,1,7,9,7,9,7]
    输出:1
     

    限制:

    1 <= nums.length <= 10000
    1 <= nums[i] < 2^31

    来源:力扣(LeetCode)
    链接:https://leetcode.cn/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-ii-lcof
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

     

    首先我们可以采用map映射的方法,统计所有元素出现的次数,然后将出现次数为1的数据返回。但是同样,这种算法虽然能够完成任务,但是非常低效。

    1. class Solution {
    2. public:
    3. int singleNumber(vector<int>& nums) {
    4. map<int ,int> record;
    5. for(auto num:nums)
    6. {
    7. record[num]++;
    8. }
    9. for(auto num:nums)
    10. {
    11. if(record[num]==1)
    12. {
    13. return num;
    14. }
    15. }
    16. return 0;
    17. }
    18. };

    这里我们可以采用这样的方法,就是统计全部数据的每一个二进制位上1的个数,然后全部都对3取模。因为我们从题目中知道,只有一个数据出现了一次,其余的数据全部都出现了三次,所以对三取模就相当于将这三个相同的数据全部都抵消掉了,而剩下的恰好就是那个仅出现了一次的数据 

    1

    3

    3

    3

    4

    4

    4

    001

    011

    011

    011

    100

    100

    100

    上面是我们的样例数据,从中我们可以观察到就1出现了一次,其余的3和4都出现了三次,此时我们分别将二进制位从右往左数第三位的全部数据相加,第二位的全部数据相加,第一位的全部数据相加

    1001
    3011
    3011
    3011
    4100
    4100
    4100

    从上面这张表格中,我们可以很清晰地看出从右往左第三位全部相加是3,第二位全部相加是3,第一位全部相加是4,然后我们分别对这些相加的结果取模,就会得到0,0,1, 将这三位拼接起来就是001,也就是我们上面仅出现了一次的数据元素1。

    1. class Solution {
    2. public:
    3. int singleNumber(vector<int>& nums) {
    4. //创建一个大小为32的容器
    5. //因为我们一个int的大小是4个字节,每个字节又是8个比特位
    6. vector<int>binary_digit(32);
    7. //遍历我们的数据
    8. for(int i=0;isize();i++)
    9. {
    10. //point为我们当前所计算的是第几位的数据
    11. int point=0;
    12. //将我们容器中当前位置的数据拷贝出来
    13. int tmp=nums[i];
    14. //循环遍历,将这个数据转化成二进制位,然后每一位都加到对应的
    15. //binary_digit位上
    16. while(tmp)
    17. {
    18. binary_digit[point]+=tmp%2;
    19. //右移一位,获取下一个比特位的数据
    20. tmp=tmp>>1;
    21. //point++,准备存储下一个比特位的数据
    22. point++;
    23. }
    24. }
    25. //result就是我们要返回的结果
    26. int result=0;
    27. //遍历我们的二进制的容器元素,分别将其中的每一位都对3取模,
    28. //然后将每一位从前到后拼接起来,组成我们的结果
    29. for(int i=0;isize();i++)
    30. {
    31. result+=(binary_digit[i]%3)*(1<
    32. }
    33. return result;
    34. }
    35. };

     

  • 相关阅读:
    不知道用什么图表展示数据?看这份图表选择指南就够了
    Apache Spark 的基本概念和在大数据分析中的应用 103.219.31.8
    Java 8 内存管理原理解析及内存故障排查实践
    海思3559万能平台搭建:OSD功能的优化
    javascript的AMD模式
    自动化测试基础简介(本质)
    Linux防火墙之SNAT与DNAT
    【无标题】
    【ROS入门】创建工作空间与功能包
    【无标题】
  • 原文地址:https://blog.csdn.net/weixin_62684026/article/details/126449032