作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


题目地址:https://leetcode.com/problems/single-number-iii/description/

题目描述

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?

题目大意

一个数组中,有些元素出现了两次,有两个元素各自只出现1次,找出这两个元素。

解题方法

异或

想到这个系列的第一个题,就是找出单个的只出现一次的字符。做法是异或操作。这个题也是用异或。

把所有的数字进行一次异或,得到的是只出现了一次的两个数字的异或。

这两个数字不等,因此他们的二进制必定至少1位不同,即异或结果中为1的那位(一个数字的该位为1,另个数字的该位为0)。找出从右向左的第一个不同的位置(异或值为1的位置),给mask在该位置设置成1,mask的其余位置是0. mask存在的意义在于我们能通过该位置来分辨出两个只出现了一次的数字。

然后技巧性的来了:再进行一次异或操作。

每个数字都跟mask相与。通过与的结果为0和为1,即可区分出两个数字。

我刚开始有点不明白的是,为什么把所有的元素都重新异或了?其实,因为除了这两个元素以外,其他的元素都出现了两次,这两次相同的数字的和mask的与操作的结果是相同的,所以会被异或两次抵消掉。

一言以蔽之,先通过异或找出两个元素的异或结果。再根据异或结果的出现为1的位置作为mask,mask的二进制只有1位是1,也就是只看两个元素的该位置。最后,通过与操作判断该位置是0还是1区分两个元素。

参考:https://segmentfault.com/a/1190000004886431

代码:

class Solution(object):
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
xor = 0
num1, num2 = 0, 0
for num in nums:
xor ^= num
mask = 1
while xor & mask == 0:
mask = mask << 1
for num in nums:
if num & mask == 0:
num1 ^= num
else:
num2 ^= num
return [num1, num2]

C++代码如下:

class Solution {
public:
vector<int> singleNumber(vector<int>& nums) {
int res = 0;
for (int n : nums) res ^= n;
int a = 0, b = 0;
int mask = 1;
while ((mask & res) == 0) mask <<= 1;
for (int n : nums) {
if (n & mask)
a ^= n;
else
b ^= n;
}
return {a, b};
}
};

字典

使用字典直接求只出现一次的数字即可。

class Solution(object):
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
count = collections.Counter(nums)
res = []
for num, c in count.items():
if c == 1:
res.append(num)
return res

C++代码如下:

class Solution {
public:
vector<int> singleNumber(vector<int>& nums) {
map<int, int> count;
for (int n : nums) count[n] ++;
vector<int> res;
for (auto p : count)
if (p.second == 1)
res.push_back(p.first);
return res;
}
};

日期

2018 年 3 月 3 日
2018 年 11 月 24 日 —— 周六快乐
2018 年 12 月 10 日 —— 又是周一!

【LeetCode】260. Single Number III 解题报告(Python & C++)的更多相关文章

  1. LeetCode 260. Single Number III(只出现一次的数字 III)

    LeetCode 260. Single Number III(只出现一次的数字 III)

  2. [LeetCode] 260. Single Number III 单独数 III

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

  3. [LeetCode#260]Single Number III

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

  4. LeetCode - 136. Single Number - ( C++ ) - 解题报告 - 位运算思路 xor

    1.题目大意 Given an array of integers, every element appears twice except for one. Find that single one. ...

  5. Java [Leetcode 260]Single Number III

    题目描述: Given an array of numbers nums, in which exactly two elements appear only once and all the oth ...

  6. LeetCode 260 Single Number III 数组中除了两个数外,其他的数都出现了两次,找出这两个只出现一次的数

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

  7. Leetcode 260 Single Number III 亦或

    在一个数组中找出两个不同的仅出现一次的数(其他数字出现两次) 同样用亦或来解决(参考编程之美的1.5) 先去取出总亦或值 然后分类,在最后一位出现1的数位上分类成 ans[0]和ans[1] a&am ...

  8. [LeetCode] 260. Single Number III(位操作)

    传送门 Description Given an array of numbers nums, in which exactly two elements appear only once and a ...

  9. leetcode 136 Single Number, 260 Single Number III

    leetcode 136. Single Number Given an array of integers, every element appears twice except for one. ...

随机推荐

  1. Oracle-常用表的查询、增加列、删除列、修改列值功能【增删改查】

    #查看表 select * from `竟企区域数据分析` #在表第一列新增名为"年月"的列alter table `竟企区域数据分析` add column 年月 varchar ...

  2. kubernetes部署 docker 容器

    docker 容器相对比较简单,不涉及认证授权,只需要本地启动起来即可,唯一需要注意就是添加flannel网络. # yum remove docker-latest-logrotate docker ...

  3. c#跳转

    Response.Redirect(EditUrl("MEUID", lblMEUID.Text, "Page2", "PageOneMK" ...

  4. 巩固javawbe第二天

    巩固内容: <!DOCTYPE> 声明 <!DOCTYPE>声明有助于浏览器中正确显示网页. 网络上有很多不同的文件,如果能够正确声明HTML的版本,浏览器就能正确显示网页内容 ...

  5. 强化学习实战 | 表格型Q-Learning玩井字棋(一)

    在 强化学习实战 | 自定义Gym环境之井子棋 中,我们构建了一个井字棋环境,并进行了测试.接下来我们可以使用各种强化学习方法训练agent出棋,其中比较简单的是Q学习,Q即Q(S, a),是状态动作 ...

  6. 日常Javaweb 2021/11/19

    Javaweb Dao层: //连接数据库,实现增查功能 package dao; import java.sql.Connection; import java.sql.DriverManager; ...

  7. Redis | 第11章 服务器的复制《Redis设计与实现》

    目录 前言 1. 旧版复制功能的实现 1.1 同步与命令传播 1.2 旧版复制功能的缺陷 2. 新版复制功能的实现 2.1 部分重同步的实现原理 3. PSYNC 命令的实现 4. 复制的详细步骤 4 ...

  8. nodejs-Path模块

    JavaScript 标准参考教程(alpha) 草稿二:Node.js Path模块 GitHub TOP Path模块 来自<JavaScript 标准参考教程(alpha)>,by ...

  9. Netty实现Socket

    Netty实现Socket 从Java1.4开始, Java引入了non-blocking IO,简称NIO.NIO与传统socket最大的不同就是引入了Channel和多路复用selector的概念 ...

  10. C语言编辑链接

    库函数(Library Files)库函数就是函数的仓库,它们都经过编译,重用性不错.通常,库函数相互合作,来完成特定的任务.比如操控屏幕的库函数(cursers和ncursers库函数),数据库读取 ...