leetcode--Single Number II

来源:互联网 发布:facebook视频下载软件 编辑:程序博客网 时间:2024/06/05 09:05

题目描述

Given an array of integers, every element appears three times except for one. Find that single one.

Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

解题思路

之前做过了数组中其他数出现两次,仅有一个出现一次的,直接用所有元素异或就行了(只要是偶数次,都可以用这个方法),本题变为其他元素出现3次,而且时间复杂度要求线性,空间为常数。

方法一:

同Single Number方法一样,删除数组中重复出现的数字,输出最后剩下的或者没有重复的数字即可http://blog.csdn.net/sinat_24520925/article/details/45576735

代码如下:

class Solution {public:    int singleNumber(vector<int>& nums) {       if(nums.size()==1) return nums[0];while(nums.size()>1){int temp=nums[0];int flag=0;for (int i=1;i<nums.size();i++){if (nums[i]==temp){nums.erase(nums.begin()+i);if (flag==1){nums.erase(nums.begin());break;}flag++;i--;}}if (!flag)  {  return nums[0];  }  }return nums[0];    }};

方法二:

  int 数据共有32位,可以用32变量存储 这 N 个元素中各个二进制位上  1  出现的次数,最后 在进行 模三 操作,如果为1,那说明这一位是要找元素二进制表示中为 1 的那一位。

例如:A[]={2,3,4,3,2,2,3}

0010

0011

0100

0011

0010

0010

0011

= -0-1-6-3-(1的个数)

0100

代码如下:

int bitflag[32]={0};int res=0;for (int i=0;i<32;i++){for (int j=0;j<nums.size();j++){bitflag[i]+=(nums[j]>>i)&1;}res|=(bitflag[i]%3)<<i;}return res;

方法三:

这是一个更快一些的解法,利用三个变量分别保存各个二进制位上 1 出现一次、两次、三次的分布情况,最后只需返回变量一就行了。代码如下:

class Solution {public:    int singleNumber(vector<int>& nums) {       int one=0,two=0,three=0;for (int i=0;i<nums.size();i++){two|=one&nums[i];one=one^nums[i];three=one&two;one=one&(~three);two=two&(~three);}return one;    }};

方法一虽然简单易于理解但是它的的时间复杂度不是线性的,平均复杂度为O(n*n);

方法二时间复杂度为O(32*n),是线性的,且是通用的,当数组中的重复元素变为r的时候,模r即可;

方法三比方法二快,时间复杂度为O(n),但是不是通用的,且理解起来有点难度。



0 0