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; }

浙公网安备 33010602011771号