p70 只出现一次的数字II (leetcode 137)

一:解题思路

这道题目和之前的单身数字的题目有点像。那个题目是每个数子都出现2次然后找到只出现1次的那个数字。那个题目的核心是异或的思想。类比过来这道题目

二:完整代码示例 (C++版和Java版)

方法一:Time:O(n),Space:O(1) 方法一比方法二容易理解 

方法二:Time:O(n),Space:O(1)

方法一C++:

class Solution {
public:
    int singleNumber(vector<int>& nums) 
    {
        int result = 0;
        for (int bit = 0; bit < 32; bit++)
        {
            int sum = 0;
            for (int num : nums)
                sum += (num >> bit) & 1;
            if (sum % 3 == 1) result |= (1 << bit);
        }

        return result;
    }
};

方法二C++:

class Solution {
public:
    int singleNumber(vector<int>& nums) 
    {
        int bt1 = 0;
        int bt2 = 0;
        int bt3 = 0;

        for (int i = 0; i < nums.size(); i++)
        {
            bt2 = bt2 | (bt1&nums[i]);
            bt1 = bt1 ^ nums[i];
            bt3 = bt1 & bt2;
            bt1 = bt1 & (~bt3);
            bt2 = bt2 & (~bt3);
        }

        return bt1;
    }
};

方法一Java:

class Solution {
        public int singleNumber(int[] nums)
        {
              int result=0;
              for(int bit=0;bit<32;bit++)
              {
                  int sum=0;
                  for(int num:nums)
                      sum+=(num>>bit)&1;
                  if(sum%3==1) result|=(1<<bit);
              }

              return result;
        }
    }

方法二Java:

class Solution {
    public int singleNumber(int[] nums) 
    {
           int bt1=0;
           int bt2=0;
           int bt3=0;
           
           for(int i=0;i<nums.length;i++)
           {
               bt2=bt2|(bt1&nums[i]);
               bt1=bt1^nums[i];
               bt3=bt1&bt2;
               bt1=bt1&(~bt3);
               bt2=bt2&(~bt3);
           }
           
           return bt1;
    }
}

 改编一下:前面我们做了只出现一次的数字,其余数字要么出现2次,要么出现3次。那么是否可以扩展到其余数字出现n次,只有一个数字只出现1次呢?当然可以(这个是一位大佬给出的方案,呵呵)

#include <iostream>
#include <vector>

using namespace std;

void NumToAcc(unsigned int num, int acc[], unsigned int n)
{
    int i = 0;

    for (i = 0; i < 32; i++)
    {
        acc[i] = (acc[i]+((num>>i)&1)) % n;
    }
}

int AccToNum(int acc[])
{
    int ret = 0;
    int i = 0;

    for(i=0;i<32;i++)
    {
        ret = ret | ((!!acc[i]) << i);
    }

    return ret;
}

int Solution(int array[], unsigned int len, unsigned int n)
{
    int i = 0;
    int ret = 0;

    if (n % 2)
    {
        int acc[32] = {0};

        for (int i = 0; i < len; i++)
        {
            NumToAcc(array[i],acc,n);
        }

        ret = AccToNum(acc);
    }
    else
    {
        for (i = 0; i < len; i++)
        {
            ret = ret ^ array[i];
        }
    }

    return ret;
}

int main()
{
    int a[] = {1,1,1,2};

    printf("%d\n",Solution(a,sizeof(a)/sizeof(*a),3));

    return 0;
}

 

posted @ 2020-03-25 17:05  repinkply  阅读(158)  评论(0)    收藏  举报