题目:singleNumber

Given an array of integers, every element appears twice except for one. Find that single one.
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

给一个数组里面除了唯一的一个数只出现一次,其他每个数都重复了一次。

要求:线性的时间复杂度,和O(1)的空间复杂度

思路:

如果不要求线性的时间复杂度,则可以考虑用排序的方法,成熟稳定,又有很好的通用性。

但是,如果要保证线性的时间复杂度,则可以考虑使用hash_map来找单个出现的数字。

通常思路里面效率的瓶颈在于如何确定当前元素是前面已经出现过的元素,此时可以通过hash_map来确保在O(1)的时间复杂度里确定当前元素是否出现过。

我用删除的方法来降低冲突率,同时,方便最后找到最终的singleNumber。

/**
*Given an array of integers, every element appears twice except for one. Find that single one.
*Note:
*Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
**/
/**空间复杂度O(n),时间复杂度O(n)但是依赖map的性能**/
int LeetCode::singleNumberMap(vector<int>& nums){
hash_map<int,int> hmp;
auto it = nums.cbegin();
while (it != nums.cend()){
auto temp = hmp.find(*it);
if (temp != hmp.cend()){//找得到当前元素,说明它在前面出现过
//(*temp).second = 2;
hmp.erase(temp);//删除重复元素
}
else{
hmp.insert(make_pair(*it,));//插入首次出现的元素
}
++it;
}
if (hmp.size() == ){//如果最终存在singleNumber
auto ret = hmp.begin();
return (*ret).first;
}
return -;//不存在,则返回-1
}

思路:

使用异或的方法;

因为元素是数字,且数组保证只重复两次;可以考虑使用异或的方法,来直接求出单一数字。

这个方法比上面的更高效,且空间复杂度O(1),而上面的空间复杂度O(n)。

/**
空间复杂度O(1),时间复杂度O(n)
使用异或来求单个数字
**/
int LeetCode::singleNumberXOR(vector<int>& nums){
int sum = ;
auto it = nums.cbegin();
while (it != nums.cend()){
sum = sum ^ (*it);//异或
++it;
}
return sum;
}

题目:singleNumberII

Given an array of integers, every element appears three times except for one, which appears exactly once. Find that single one.
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

给一个数组里面除了唯一的一个数只出现一次,其他每个数都重复了两次(即出现3次)。

要求:线性的时间复杂度,和O(1)的空间复杂度

思路:

使用hash_map同样可以求出来,思路跟第一个是一样的。

但是,如何用异或更高效的找到singleNumber呢?

首先还是对每个元素异或,保留奇数次出现的元素(once);

同时,增加一个变量accumulate |= (*it) & once;

  上面的算式能够保留出现2次以上的元素;(it表示当前元素)

  例如:once中出现过奇数次则表示保留了该数字,则必然出现2次以上,于是上面表达式的结果确实是保留了当前元素;

     once出现了偶数次,表示未保留该数字,则取决于accumulate中是否保留该数字,没有则是0。

  因此,上面表达式确实能够保留出现2次以上的元素。

然后出现3次则表示,上面两个值都是保留当前元素的状态,于是在异或一次就消除了出现3次的元素。

int LeetCode::singleNumber(vector<int>& nums){
//once标记出现奇数次的数字,accumulate标记出现2次以上的数字
int once = ,accumulate = ;
auto it = nums.cbegin();
while (it != nums.cend()){
//once中出现过奇数次则表示保留了该数字,则必然出现2次以上;
//once出现了偶数次,表示未保留该数字,则取决于accumulate中是否保留该数字,没有则是0
accumulate |= (*it) & once;// 只要第二次或者以上出现,就为1
once ^= (*it);// 出现奇数次保留,偶数次抛弃
int t = once & accumulate;// 第三次的时候one和accumulation都保留了该位的值
once &= ~t; // 清零出现三次的该位的值
accumulate &= ~t; //once = (once ^ (*it)) & ~accumulate;
//accumulate = (accumulate ^ (*it)) & ~once;
++it;
}
return once;
}

上面一连串的求解,还可以缩减成下面两个表达式:

once = (once ^ (*it)) & ~accumulate;

accumulate = (accumulate ^ (*it)) & ~once;

题目:Single Number III

Given an array of numbers nums, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once.

For example:

Given nums = [1, 2, 1, 3, 2, 5], return [3, 5].

Note:

  1. The order of the result is not important. So in the above example, [5, 3] is also correct.
  2. Your algorithm should run in linear runtime complexity. Could you implement it using only constant space complexity?

给一个数组里面除了两个数只出现一次,其他每个数都出现了两次。

要求:线性的时间复杂度,和O(1)的空间复杂度。

思路:

设数组为A[],其中两个只出现一次的数字是A,B

根据第一个问题的思路,如果只有一个数字可以直接将所有数字异或得到。因此,该问题如果异或所有数字得到的值是A^B。

那么,如果能将A,B区分开就可以了;异或表示两个数字中不相同的位是1,即如果A^B的某一位是1,表示A和B中对应的该为分别为0和1,或1和0。

反之,只要将该位为1的所有数从新异或一遍,就能的到A或B中的一个数字,于是就区分开了。

vector<int> LeetCode::singleNumber3(vector<int>& nums){
int xorall = , first1 = ;//第一个1
vector<int>result(, );
for (auto i : nums){//求A^B
xorall ^= i;
}
first1 = xorall & (~(xorall - ));//求A^B中第一个1的值,例如A = 4,B = 8,A^B = 12,first1 = (0100 ^ 1000) & (0100) = 4
for (auto i : nums){
if (first1 & i)result[] ^= i;//所有A^B第一个1相同位置为1的元素异或
else result[] ^= i;;
}
return result;
}

[LeetCode]singleNumber的更多相关文章

  1. LeetCode——single-number系列

    LeetCode--single-number系列 Question 1 Given an array of integers, every element appears twice except ...

  2. leetcode — single-number

    /** * Source : https://oj.leetcode.com/problems/single-number/ * * * Given an array of integers, eve ...

  3. Leetcode SingleNumber I & II & III 136/137/260

    SingleNumber I: 题目链接:https://leetcode-cn.com/problems/single-number/ 题意: 给定一个非空整数数组,除了某个元素只出现一次以外,其余 ...

  4. Leetcode 136 137 260 SingleNumber I II III

    Leetccode 136 SingleNumber I Given an array of integers, every element appears twice except for one. ...

  5. LeetCode 2: single-number II

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

  6. LeetCode 1: single-number

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

  7. single-number leetcode C++

    Given an array of integers, every element appears twice except for one. Find that single one. Note: ...

  8. [LeetCode] Single Number III 单独的数字之三

    Given an array of numbers nums, in which exactly two elements appear only once and all the other ele ...

  9. [LeetCode] Single Number II 单独的数字之二

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

随机推荐

  1. 试试 python-dotenv,避免敏感信息被硬编码到代码中

    我们开发的每个系统都离不开配置信息,例如数据库密码.Redis密码.邮件配置.各种第三方配置信息,这些信息都非常敏感,一旦泄露出去后果非常严重,被泄露的原因一般是程序员将配置信息和代码混在一起导致的. ...

  2. Nginx总结(一)Linux下如何安装Nginx

    以前写过一些Nginx的文章,但都是用到什么说什么,没有一个完整系统的总结.趁最近有时间,打算将Nginx相关的内容重新整理一下.nginx系列文章地址如下:https://www.cnblogs.c ...

  3. 集成 Spring Boot 常用组件的后台快速开发框架 spring-boot-plus 国

    spring-boot-plus是一套集成spring boot常用开发组件的后台快速开发框架 Purpose 每个人都可以独立.快速.高效地开发项目! Everyone can develop pr ...

  4. Mybatis 中的<![CDATA[ ]]>浅析

    在使用mybatis 时我们sql是写在xml 映射文件中,如果写的sql中有一些特殊的字符的话,在解析xml文件的时候会被转义,但我们不希望他被转义,所以我们要使用<![CDATA[ ]]&g ...

  5. Liunx软件安装之Zabbix监控软件

    Zabbix 是什么 zabbix(音同 za:bix)是一个基于 WEB 界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案. zabbix 能监视各种网络参数,保证服务器系统的安全运营 ...

  6. MySQL之备份和还原

    在实际项目中对于数据库的安全是重中之重,为防万一我们需要做好备份工作.备份分为全量备份和增量备份,今天我们就来实践下备份和还原操作. 一.为什么需要备份 在生产环境中数据库可能会遭遇到各种各样的不测从 ...

  7. Lock同步锁

    Lock同步锁 一.前言 在Java 5.0 之前,协调共享对象的访问时可以使用的机制只有synchronized 和volatile .Java 5.0 后增加了一些新的机制,但并不是一种替代内置锁 ...

  8. Github资源下载

    自己收集的一些日常使用软件.编程书籍以及自己动手实践的程序,欢迎下载. 收集维护不易,喜欢请Star或Fork支持呀,(^-^)V. 所有资源均自己制作或收集自网络,如有侵权请联系删除. 友情链接 G ...

  9. ROS中local costmap的原点坐标系

    local costmap是一个依赖于其他坐标系存在的坐标系统,它并不维护自己的坐标系,而是在另一个坐标系中设定坐标原点,然后记下自己的宽与高.它使用数据结构nav_msgs/OccupancyGri ...

  10. mongodb 启动 WARNING: soft rlimits too low, transparent_hugepage/enabled is 'always'. never

    今天启动mongodb的时候,之前一直没注意,今天发现又warning,想整一整. 下面是告警 2019-09-05T12:00:55.271+0800 I CONTROL [initandliste ...