liyanbo的个人博客分享 http://blog.sciencenet.cn/u/liyanbo

博文

leetcode-Single Number1,2,3

已有 1962 次阅读 2015-9-11 20:43 |个人分类:C++|系统分类:生活其它

最近开始刷题,特别喜欢系列的题,明显感觉到思路的循序渐进.

/**
* @file Single_Number.cc
* @brief
* @version 0.1.00
* @date 2015-09-10
*/
#include <iostream>
#include <vector>
#include <cassert>
#include <cmath>
using namespace std;
//2*k+1 按位异或,自己与自己异或为0,0与其他数异或是其他数
int singleNumber_1(const vector< int >& nums) {
   int ans = 0;
   for (int i=0; i<nums.size(); i++) {
       ans ^= nums[i];
   }
   //cout<<ans<<endl;
   return ans;
}
//3*k+1 转为2进制,出现3遍的数,对应的二进制数也出现3遍
int singleNumber_2(const vector<int>& nums) {
   assert(nums.size()%3 == 1);
   int ans = 0;
   for (int i=0; i<8*sizeof(i); i++) {
       int MASK = (1<<i);
       int sum_bit = 0;
       for(int j=0; j<nums.size(); j++) {
           sum_bit += ((MASK & nums[j])==0)?0:1;
       }
      // cout<<sum_bit<<"t"<<endl;
       ans |= ((sum_bit%3)==0?0:MASK);
   }
   return ans;
}
//m*k的都可以做,m为偶数用_1,为奇数用_2

//2*k+2 如果能转化为两个2*k'+1就很容易解决了.将所有数异或相当于将两个只出现一次的数异或.必然可以知道,这两个数某一位上不同,按这个位上的不同就可以将问题化为子问题了.
vector <int> singleNumber_3(const vector< int >& nums) {
   
   assert(nums.size()%2 == 0);
   int diff = singleNumber_1(nums);
   int i=0;
   int temp;
   for (; i<sizeof(diff)*8; i++) {
      temp = (1<<i);
      cerr<<temp << "t" << (temp&diff) <<endl;
      if ((temp&diff) > 0)
          break;
   }
   cerr<<"aa"<<temp<<endl;
   //根据i上的bit值分为两组
   vector< int > one;
   vector< int > zero;
   for (int j=0; j<nums.size(); j++) {
       if ((temp&nums[j]) > 0) {        //按位与的优先级特别低
           one.push_back(nums[j]);
           cerr<<"bb"<<nums[j]<<endl;
       } else {
           zero.push_back(nums[j]);
           cerr<<"cc"<<nums[j]<<endl;
       }
   }
   vector< int > ans;
   ans.push_back(singleNumber_1(one));
   ans.push_back(singleNumber_1(zero));
   return ans;
}
//网上找的改进版
vector <int> singleNumber_3_2(const vector<int> & nums) {
   assert(nums.size()%2 == 0);
   int temp = 0;
   for (int i=0; i<nums.size(); i++) {
       temp ^= nums[i];
   }

   int MASK = (temp&(~(temp-1)));//可以找到为1的最低位

   int A=0;
   int B=0;
   for (int i=0; i<nums.size(); i++) {
       if ((MASK&nums[i])==0) {
          A ^= nums[i];
       } else {
          B ^= nums[i];
       }
   }
   cerr << A << "t" << B <<endl;
   vector< int > ans(2);
   ans[0] = A;
   ans[1] = B;
   return ans;
   //return vector<int> ({A,B});

}
//3*k+2 同_3分为两个3*k'+1,用_2找到一个不同bit位
int main() {
   int n;
   //cout<<sizeof(n)<<endl;
     
   while(cin>>n) {
       //cout<<sqrt(n)<<endl;
       vector<int> nums(n);
       for (int i=0; i<nums.size(); i++) {
           cin>>nums[i];
       }
       singleNumber_3_2(nums);
   }

   return 0;
}



https://blog.sciencenet.cn/blog-1515646-920207.html

上一篇:师姐代码心得-1解析命令行
下一篇:EM算法-1
收藏 IP: 159.226.43.*| 热度|

1 苟家宁

该博文允许注册用户评论 请点击登录 评论 (0 个评论)

数据加载中...

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-7-18 01:36

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部