面试40-一个数组,有2个数字出现奇数次,其余都是偶数次,求这两个数字O(n) O(1)

#include<iostream>
using namespace std;
// 题目:数组中只有不多于两个数字出现次数是奇数次,其他都是偶数次,求出出现奇数次的数字(不含0的数组)

//思想:
/*
(1)如果只有一个数字是奇数次,直接对数组进行按位异或运算,得到的结果就是该数
(2)如果有俩个,可以先对数组异或,得到的结果(就是两个奇数次的数字异或的结果),必定至少包含一个1,可以根据这个1在的位置,把数组分为两个部分
     则两个奇数次的数字必定分别在两个部分,而相同的数次必定在同一组,则可以对两个部分分别求异或得到答案
*/

std::pair<int, int> findTwoOddOccurrences(std::vector<int>& nums) {
  // Step 1: 异或所有数字
  int xorResult = 0;
  for (int num : nums) {
    xorResult ^= num;
  }
  // Step 2: 找到两个不同数字的不同位
  int diffBit = 1;
  while ((xorResult & diffBit) == 0) {
    diffBit <<= 1;
  }
  // Step 3: 分别异或两个子数组的数字
  int firstOdd = 0, secondOdd = 0;
  for (int num : nums) {
    if ((num & diffBit) == 0) { // 这一位为0的数字 其余数字是偶数个不影响异或结果
      firstOdd ^= num;
    } else { // 这一位为1的数字 
      secondOdd ^= num;
    }
  }
  return {firstOdd, secondOdd};
}

 

posted @ 2015-09-10 16:48  fchy822  阅读(1353)  评论(0编辑  收藏  举报