LINTCODE:136 只出现一次的数字(Python语言实现)
1. 题目描述
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,1] 输出: 1 |
示例 2:
输入: [4,1,2,1,2] 输出: 4 |
2. 使用列表
首先考虑到使用列表的数据结构,因为append方法每次的操作均为常数级的操作。但在检索的过程中,in方法仍是线性级别的,导致运行结果为“超出时间限制”。
[code]class Solution: def singleNumber(self, nums): """ :type nums: List[int] :rtype: int """ sn = [] for nu in nums: if nu not in sn: sn.append(nu) else: sn.remove(nu) return sn[0]
3. 使用字典
列表的in方法采用的仍是遍历的过程,此时会想到字典这个数据结构。生成键-值对,其中关键字作为键,出现次数为值。使用keys方法就可以轻松的得到键的可迭代对象,这样对关键字的检索就是常数级了。在这里,输出使用的pop方法,输入采用的基本赋值。经测试显示“通过”。
[code]class Solution: def singleNumber(self, nums): """ :type nums: List[int] :rtype: int """ sd = {} for nu in nums: if nu in sd.keys(): sd.pop(nu) else: sd[nu] = 1 return list(sd.keys())[0]
需要注意的地方是:当字典中的键值需要导出的时候,使用keys方法得到的是可迭代对象,所以用list方法列表化。
4. 使用集合
集合的思想就是简化出来字典的“键”,在这里,输入采用的add方法,输出采用的remove方法。返回值的int类型采用的pop方法。平台上测试的结果,是“通过”,但要比使用字典的数据结构要慢。
[code]class Solution: def singleNumber(self, nums): """ :type nums: List[int] :rtype: int """ sd = set() for nu in nums: if nu in sd: sd.remove(nu) else: sd.add(nu) return sd.pop()
5. 如何不使用额外空间实现?
时间复杂度的线性级别很容易采用数据结构的特性来弥补,但空间复杂度的常数级,也就意味着只能使用数个中间变量作为中转来实现。
首先想到的是加减操作,但运算符的判定是要建立在有序数组的基础上。所以可以采用先排序,再设置标志位flag进行加减的操作。函数sorted()采用的是就地操作,一定程度上也算是没有添加额外的辅助空间。经测试,显示“通过”。
[code]class Solution: def singleNumber(self, nums): """ :type nums: List[int] :rtype: int """ sn, flag = 0, True for nu in sorted(nums): if flag: sn += nu flag = False else: sn -= nu flag = True return sn
那有没真正意思上的不使用额外空间的线性级别的算法呢?是有的,这里是借助异或运算符的魔法。异或运算符在二进制的位数上,相同则为0,不同为1,常用于不设置中间变量传递值就交换两个数。
在这里,异或运算符的经典之处,在于存储二进制各位上的状态值。相同的情况下就会抵消,留出来的就是单个的。比如:
数组:【1, 3, 2, 1, 2】 |
1:0 0 1 3:1 0 1 2:0 1 0 1:0 0 1 2:0 1 0 |
竖向看的话,明显的相互抵消,尽管有先后顺序,但值并没有发生变化。
[code]class Solution: def singleNumber(self, nums): """ :type nums: List[int] :rtype: int """ sn = 0 for nu in nums: sn ^= nu return sn
阅读更多
- 【LeetCode-面试算法经典-Java实现】【136-Single Number(仅仅出现一次的数字)】
- 【LeetCode-面试算法经典-Java实现】【136-Single Number(只出现一次的数字)】
- LeetCode 136 Single Number(数组中只出现一次的数字)
- 数据结构与算法分析笔记与总结(java实现)--数组10:数组中只出现一次的数字
- 统计n个随机数(随机0~10),每出现一次就用*号在数字下面写一次*【c语言实现】
- 一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。 找出这两个数字,编程实现
- 编程实现: 一组数据中只有一个数字出现了一次。其他所有数字都是成对出现的。 请找出这个数字。(使用位运算)
- C语言- 一个数组中只有两个数字是出现一次,其他所有数字都出现了两次,找出这两个数字,编程实现。
- 用异或实现查找只出现一次的数字
- 《剑指offer》编程题java实现(十一):数组中只出现一次的两个数字
- 一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。找出这两个数字,编程实现。
- python实现:使用二分查找,查找有序数组中,一个数字最后出现的下标
- 程序员面试100题(算法)之找出数组中两个只出现一次的数字(位运算实现)
- python实现字符串只出现一次的字符
- 一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。 找出这两个数字,编程实现
- leetcode解题之136 #Single Number Java版(只出现一次的数字)
- 一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。 找出这两个数字,编程实现。
- 1.求第n个斐波那契数(非递归实现)。 2.一个数组中只有两个数字是出现一次,其他所有数字都出现 了两次。 找出这两个数字,编程实现。
- 一个数组中只有两个数字是出现一次,其他所有数字都成对出现,找出这两个数字,编程实现
- 任意一个英文的纯文本文件,统计其中的单词出现的个数(shell python 两种语言实现)