题目

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?

代码

class Solution {
public:
int singleNumber(vector<int>& nums) {
int result = ;
const int W = sizeof(int)*;
int *count = new int[W]();
for (size_t i = ; i < nums.size(); ++i)
{
for (size_t j = ; j < W; ++j)
{
count[j] += (nums[i] >> j) & ;
}
}
for (size_t i = ; i < W; ++i)
{
if ( count[i]%!= )
{
result += ( << i);
}
}
delete []count;
return result;
}
};

Tips:

1. 算法原理:由于都是int型的,只需要记录每个bit上1出现的次数;如果1出现的次数不是3的倍数,则将该位置置为1,并赋值到result中。

这道题主要是熟悉下位运算的各种操作,有时巧用位运算,可以大大提升代码效率。

================================================================

学习了另一种解法,代码如下:

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

参考链接:https://leetcode.com/discuss/857/constant-space-solution

简单说就是,用二进制模拟三进制运算。

循环体中的五条语句分别做了如下的事情:

1. 算上nums[i]之后,1出现了两次的bit位数有哪些

(包括两种情况:a.原来就是2次的,nums[i]在该bit上是0;原来是1次的,nums[i]在该bit上是1)。

2. 算上nums[i]之后,1出现了一次的bit位数有哪些。

3. 算上nums[i]之后,1出现了三次的bit位数有哪些

4和5. 满3进位,清空。

这里可能会有一个疑问:1出现次数为一和为二的能否算重了?

假设nums[i]在某一个bit上是0:

  a. 算two的时候,这一位不会影响原来two这一bit的取值。

  b. 算one的时候,相当于该bit与0异或,保持不变。

假设nums[i]在某一个bit上是1:

  a. 算two的时候,如果one在该bit上也是1,则two这一bit取1,如果one在这一位上是0,则two这一bit上不变。

  b. 算one的时候,相当于该bit与1异或,取反。如果one原来是1,则进位,one置为0;如果one原来是0,则变为1。

对比颜色相同的两端文字,可以知道是不会算重复的。

想到这里还有一个疑问:two = two | (one & nums[i]),如果某一bit上two原来就是1,并且还有进位了,那这?

这种case是不可能出现的:因为one two three初始都是0,假如连着三个nums[i]在某个bit上都为1,则three在该bit上就为1了。后面两条语句,就保证了two和one被清空了,因此永远不会出现two原来是1并且有进位的情况。

======================================================

第二次过这道题,想了一段时间。大体思路已经想出来了,但是位运算操作(“左移多少位再跟1进行与操作”这些的技巧)参考了书上的code。代码还是一次AC了。

class Solution {
public:
int singleNumber(vector<int>& nums) {
int int_bits = sizeof(int)*;
vector<int> count(int_bits,);
// count each '1' in each bit
for ( int i=; i<nums.size(); ++i )
{
for ( int j=; j<count.size(); ++j )
{
count[j] += (nums[i] >> j) & ;
count[j] = count[j] % ;
}
}
// extract single number
int single = ;
for ( int i=; i<count.size(); ++i )
{
single = single + ( count[i] << i );
}
return single;
}
};

还是这种思路好记一些,二进制代替三进制运算的那个并没有印象了。

【Single Num II】cpp的更多相关文章

  1. 【Word Break II】cpp

    题目: Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where e ...

  2. 【Unique Paths II】cpp

    题目: Follow up for "Unique Paths": Now consider if some obstacles are added to the grids. H ...

  3. 【Path Sum II】cpp

    题目: Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the give ...

  4. 【Spiral Matrix II】cpp

    题目: Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order. ...

  5. 【palindrome partitioning II】cpp

    题目: Given a string s, partition s such that every substring of the partition is a palindrome. Return ...

  6. 【Jump Game II 】cpp

    题目: Given an array of non-negative integers, you are initially positioned at the first index of the ...

  7. 【Combination Sum II 】cpp

    题目: Given a collection of candidate numbers (C) and a target number (T), find all unique combination ...

  8. 【Word Ladder II】cpp

    题目: Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) ...

  9. 【N-Quens II】cpp

    题目: Follow up for N-Queens problem. Now, instead outputting board configurations, return the total n ...

随机推荐

  1. 工作中遇到的有关echarts地图和百度地图的问题

    工作中遇到的有关echarts地图和百度地图的问题 *** 前言:在做项目中需要制作一个场景是左边是柱状图,右边是地图,地图上悬浮一个按钮可以切换echarts地图和百度地图.*** 功能: 在点击左 ...

  2. 跨平台移动开发phonegap/cordova 3.3全系列教程-简介

    一.   跨平台實現架構: phonegap +asp.net+jquery mobile/jqmobi 二.   PhoneGap简介 PhoneGap是一个开源的开发框架,用来构建跨平台的使用HT ...

  3. 实战:ADFS3.0单点登录系列-前置准备

    本文为本系列第二篇,主要分为两部分进行介绍, 一.网络拓扑 二.证书制作 还是将本系列目录贴出来,方便导航 实战:ADFS3.0单点登录系列-总览 实战:ADFS3.0单点登录系列-前置准备 实战:A ...

  4. 关于docker容器内核参数修改问题

    以下内容截取自docker官方文档 地址:https://docs.docker.com/edge/engine/reference/commandline/run/#configure-namesp ...

  5. JSON.parse()与JSON.stringify()

    JSON.parse() 将字符串转成JSON 举个例子 var str = '{"name":"cn","age":"2&quo ...

  6. UVA - 1639 Candy (概率,精度)

    X表示剩下的糖数量,如果最后打开的是p对应的盒子.划分:Xi表示剩下i个糖,最后一次选的概率为p, 前面的服从二项分布.根据全概率公式和期望的线性性,求和就好了. 精度处理要小心,n很大,组合数会很大 ...

  7. Http协议--请求报文和响应报文

           http协议是位于应用层的协议,我们在日常浏览网页比如在导航网站请求百度首页的时候,会先通过http协议把请求做一个类似于编码的工作,发送给百度的服务器,然后在百度服务器响应请求时把相应 ...

  8. 【洛谷3648】[APIO2014] 序列分割(斜率优化DP)

    点此看题面 大致题意: 你可以对一个序列进行\(k\)次分割,每次得分为两个块元素和的乘积,求总得分的最大值. 区间\(DPor\)斜率优化\(DP\) 这题目第一眼看上去感觉很明显是区间\(DP\) ...

  9. mongodb索引 全文索引之相似度查询

    我们在百度搜索中,可以看到与自己搜索度内容越相关度,排在越前面,这个需求可以在mongodb中很简单度实现,mongodb的全文索引不仅可以返回相匹配的查询结果,而且可以告诉你查询结果与你的查询条件多 ...

  10. UIButton 加载网络图片

    以后就可以 用这个分类   UIButton轻松加载网络图片了, UIButton+WebCache.h #import <UIKit/UIKit.h> @interface UIButt ...