LeetCode137只出现一次的数字——位运算

题目

题目描述:给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现三次。找出那个只出现一次的元素。

说明:你的算法应该具有线性时间的复杂度。你可以不使用额外的空间来实现吗?

思路

题目要求线性复杂度,一般的算法做不到,不难想到用位运算。但怎么进行位运算,比较难想到。

b = (b ^ x) & ~a;
a = (a ^ x) & ~b;

^ 相当于除去原有元素,添加新元素, a &~  b 相当于从a集合中除去b集合中的所有元素。

int len = nums.size();
for(int i =0;i < len;++i){
   b = (b ^ nums[i]) & ~a;
   a = (a ^ nums[i]) & ~b;}

出现一次的存在b中,第二次出现从b中清除同时会存在a中,第三次出现会从b中清除。最终出现一次的都存在b中,出现两次的都存在a中

例如:[1,2,2,1,1,2,99]

b={0} {1} {1,2} {1} {0} {0} {0} {99}
a={0} {0} {0} {2}
{1,2}

{2 {0} {0}

代码

 1 class Solution {
 2 public:
 3 int singleNumber(vector<int>& nums) {
 4     int a = 0, b = 0;
 5     for (auto x : nums) {
 6         a = (a ^ x) & ~b;
 7         b = (b ^ x) & ~a;
 8     }
 9     return a;
10 }
11 };
12
13 static const auto __lamda = []() {
14     std::ios::sync_with_stdio(false);
15     std::cin.tie(nullptr);
16     return nullptr;
17 }();

参考链接:https://leetcode-cn.com/problems/single-number-ii/comments/

原文地址:https://www.cnblogs.com/lfri/p/10349846.html

时间: 2024-11-07 23:54:08

LeetCode137只出现一次的数字——位运算的相关文章

数字位运算操作与算法简单示例

我们对于位运算可能既陌生又熟悉.知道其运算方法运算过程,但不能运用好它. 首先,我们还是回顾一下Java中位运算都包含那些操作: 一.与运算(&) 运算法则:将二进制数进行按位与运算.0&0=0:0&1=0:1&1=1 : 如:0011 & 0010 = 0010: 二.或运算(|) 运算法则:将二进制数进行按位或运算.0|0 =0:1|0 = 1;  1|1=1 如:0011 & 0010 = 0011: 三.异或运算(^) 运算法则:将二进制数进行按位异

BZOJ4811 [Ynoi2017]由乃的OJ 树链剖分 位运算

原文链接 题目传送门 - BZOJ4811 题意概括 是BZOJ3668长在树上并加上修改和区间询问. 一棵树,n个节点,每一个节点有一个位运算符和一个运算数. 现在要你支持两种操作: 1. 单点修改. 2. 现在你有一个数字v,让他从x走到y,每到达一个节点进行相应的运算.v在0~z之间,让你使得运算结果最大,问v为何值. 题解 我们考虑树链剖分+线段树. 假设某一位为0或者1,那么经过一定的操作之后也是0或1. 那么,如果只有一位,那么两段就可以轻松合并了. k位也是一样,我们只需要用一堆奇

面试题40:数组中只出现一次的数字

题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字.要求时间复杂度是O(n),空间复杂度是O(1). 题目分析 剑指Offer(纪念版)P211 ① 自己与自己异或为0 ② 0与数A异或为A ③ 异或满足交换律 代码实现 void FindNumsAppearOnce(int data[], int length, int* num1, int* num2) { if (data == NULL || length < 2) return; in

数组中只出现一次的数字(剑指offer)思维有点巧

数组中只出现一次的数字 参与人数:1144时间限制:1秒空间限制:32768K 通过比例:21.75% 最佳记录:0 ms|0K(来自  牛客563536号) 题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 题目链接:http://www.nowcoder.com/practice/e02fdb54d7524710a7d664d082bb7811?rp=2&ru=/ta/coding-interviews&qru=/ta/coding

数组中只出现一次的数字

题目 一个整型数组里除了两个数字之外,其他数字都出现了两次.请找出这两个只出现一次的数字.要求时间复杂度O(n),空间复杂度O(1) 思路 我们知道如果把题目中的两个数字换成一个的话,整个数组内的元素连续异或,最终的数便是那个出现一次的数,因为异或的性质:相同为0,不同为1,所以有任何数字异或自己都是0. 换成两个数字后,我们可以继续全局异或,得到的数必然不等于0,那么也就是说二进制中必然有一位是1,比如是第K位为1,那么按照所有元素的第K位是否为1划分成两个子区间,这样,我们在这两个子区间内按

【剑指offer】数组中只出现一次的数字

一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. /*考虑过程: 首先我们考虑这个问题的一个简单版本:一个数组里除了一个数字之外,其他的数字都出现了两次.请写程序找出这个只出现一次的数字. 这个题目的突破口在哪里?题目为什么要强调有一个数字出现一次,其他的出现两次?我们想到了异或运算的性质:任何一个数字异或它自己都等于0 .也就是说,如果我们从头到尾依次异或数组中的每一个数字,那么最终的结果刚好是那个只出现一次的数字,因为那些出现两次的数字全部在异或中

数组中只出现一次的数字-剑指Offer

数组中只出现一次的数字 题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 思路 先考虑一个数组里只有一个数出现一次,其他两个数都出现两次的情况:一个数跟自己异或后为0,一个数组里只有一个数出现一次其他两次,挨个异或后最后得到的结果就是只出现一次的那个数. 我们把这个数组分为两部分,每部分只有一个数只出现一次:我们分的时候,把所有数都异或后,得到的结果肯定不为0,其实是那两个只出现一次的不同的数的异或,我们从低位到高危找到第一个不为0的那位,异

找出数组中两个只出现一次的数字

题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字.要求时间复杂度是O(n),空间复杂度是O(1). 还是理解不够深刻. 这题的主要思路还是之前的数组中只出现一次的数字的那种模式,一次遍历加上异或运算.那么这个异或的值肯定是这两个只出现一次的数字的相异或的值.那么这个值的二进制表现形式中的1的结果就表示这两个数字在该bit位上不一样.那么通过此举,我们可以以这个bit位是否为1来从整个数组中把这两个只出现一次的数字分开. 通过此举,别的出现两次的数字

【转】一个数组中有三个数字a、b、c只出现一次,其他数字都出现了两次。请找出三个只出现一次的数字。

转自:http://zhedahht.blog.163.com/ 题目:一个数组中有三个数字a.b.c只出现一次,其他数字都出现了两次.请找出三个只出现一次的数字. 分析:在博客http://zhedahht.blog.163.com/blog/static/2541117420071128950682/中我们讨论了如何在一个数组中找出两个只出现一次的数字.在这道题中,如果我们能够找出一个只出现一次的数字,剩下两个只出现一次的数字就很容易找出来了. 如果我们把数组中所有数字都异或起来,那最终的结