寻找数组中丢失的、者重复的、或者出现一次的的数的问题汇总
2014-12-22 18:18
323 查看
1. 集合增量问题
一组大小为1到n的牌,抽走一张,求抽走的是哪张牌?
此类问题特点:
输入:1)已知原始集合:或者是直接给定一个数组,或者是给一个描述,比如1到n,每个数出现一次(或2次),总之原始集合是确定的
2)改变后的集合:原始集合拿走(添加)一个或2个数之后的集合
求:少了的数,多出来的数等,其实就是求两个集合的增量
思路:题目所求就是求2个集合之间的增量(差异),所以思路就是“求差”,对原始集合求和,减去当前集合的和,就是多出来或者缺失的数;如果是少了2个数怎么办?多算一种差异,平方和的差,联列x+y= a, x^2+y^2 = b 解方程。理论上几个数都可以,既增加数,又减少数也可以,因为都是解方程,就是变量个数和方程形式的问题。
少了2个数,多了2个数,少了一个数,同时一个数多出现了一个,少了一个数,多了一个数(这个数不属于集合),这些问法都是一样的。
如果元素是连续的,可以映射到下标,则可以用桶排序思想
大小为n的数组,元素是1到n的数,但是少了一个数,同时一个数多出现了一次,求这两个数。
桶排序,尝试把每个数组元素a[i] 放在它应该出现的位置,如果那个位置已经是这个数了,说明这个数重复了;i++。最后从前往后再扫一遍,第一个位置上不是对应数的位置就是缺失的数。
2. Single number 问题,其他数都出现了k(k>1)次,只有一个数出现了一次,求这个数
分析:如果原始集合是已知的,依然可以使用2集合求差异的方法,(原始和 - 实际和 ) /( k-1) 即为所求。但这里原始集合不是给定的,需要统计unique的数,需要一个set,那还不如用最基本的map计数法。
换一种思路:考虑把出现了多次数消掉,如果k是偶数,则可用异或法;如果k是奇数,则可以用求和再求余法,出现k次的数模k为0,和里最终剩下的是那个single number %k,还是不行,再利用一个性质,小于k的数对k取模就是这个数本身,分别求single number的每一位
3 另一种single Number问题,但变化的是single number的个数
一般的数都出现2次(或者偶数次)只有k个数只出现一次。求这k个只出现一次的数。如果k = 1,直接异或法;如果k=2,先异或,找一个为1的bit位,按这一位是0还是1把所有的数分成2部分,两个出现一次的数分别在这两部分,然后各自异或法求。
如果k = 3。首先要明确3点:1)数组总数一定是奇数,2)3个不同的数异或结果有可能是0,3)两个不同的数异或必然不为0。
按第0位是0还是1分成两组,必然一个组个数是奇数一个组个数是偶数。这三个数中,偶数组要么有2个,要么没有,不能有3个或1个。所以偶数组异或为0,则说明三个数都在奇数组,递归问题。若偶数组异或不为0,则说明有两个在其中,异或奇数组得到一个数。偶数组变成k= 2的 single Number问题。
一组大小为1到n的牌,抽走一张,求抽走的是哪张牌?
此类问题特点:
输入:1)已知原始集合:或者是直接给定一个数组,或者是给一个描述,比如1到n,每个数出现一次(或2次),总之原始集合是确定的
2)改变后的集合:原始集合拿走(添加)一个或2个数之后的集合
求:少了的数,多出来的数等,其实就是求两个集合的增量
思路:题目所求就是求2个集合之间的增量(差异),所以思路就是“求差”,对原始集合求和,减去当前集合的和,就是多出来或者缺失的数;如果是少了2个数怎么办?多算一种差异,平方和的差,联列x+y= a, x^2+y^2 = b 解方程。理论上几个数都可以,既增加数,又减少数也可以,因为都是解方程,就是变量个数和方程形式的问题。
少了2个数,多了2个数,少了一个数,同时一个数多出现了一个,少了一个数,多了一个数(这个数不属于集合),这些问法都是一样的。
如果元素是连续的,可以映射到下标,则可以用桶排序思想
大小为n的数组,元素是1到n的数,但是少了一个数,同时一个数多出现了一次,求这两个数。
桶排序,尝试把每个数组元素a[i] 放在它应该出现的位置,如果那个位置已经是这个数了,说明这个数重复了;i++。最后从前往后再扫一遍,第一个位置上不是对应数的位置就是缺失的数。
2. Single number 问题,其他数都出现了k(k>1)次,只有一个数出现了一次,求这个数
分析:如果原始集合是已知的,依然可以使用2集合求差异的方法,(原始和 - 实际和 ) /( k-1) 即为所求。但这里原始集合不是给定的,需要统计unique的数,需要一个set,那还不如用最基本的map计数法。
换一种思路:考虑把出现了多次数消掉,如果k是偶数,则可用异或法;如果k是奇数,则可以用求和再求余法,出现k次的数模k为0,和里最终剩下的是那个single number %k,还是不行,再利用一个性质,小于k的数对k取模就是这个数本身,分别求single number的每一位
int singleNumber(vector<int>& nums) { vector<int> B(32); int res = 0; for (int j = 0; j < 32; ++j) {//compute each bit of the result number and then add into the result for (int i = 0; i < nums.size(); ++i) B[j] += (nums[i] >> j) & 1; // B[j]: sum of bit j; res |= (B[j] % 3) << j; } return res; }
3 另一种single Number问题,但变化的是single number的个数
一般的数都出现2次(或者偶数次)只有k个数只出现一次。求这k个只出现一次的数。如果k = 1,直接异或法;如果k=2,先异或,找一个为1的bit位,按这一位是0还是1把所有的数分成2部分,两个出现一次的数分别在这两部分,然后各自异或法求。
如果k = 3。首先要明确3点:1)数组总数一定是奇数,2)3个不同的数异或结果有可能是0,3)两个不同的数异或必然不为0。
按第0位是0还是1分成两组,必然一个组个数是奇数一个组个数是偶数。这三个数中,偶数组要么有2个,要么没有,不能有3个或1个。所以偶数组异或为0,则说明三个数都在奇数组,递归问题。若偶数组异或不为0,则说明有两个在其中,异或奇数组得到一个数。偶数组变成k= 2的 single Number问题。
相关文章推荐
- 【100题】第六十一题~第六十五题(数组中只出现一次的数、链表公共点、删除字串特定字符、寻找丑数、输出从1到最大的N 位数)
- 寻找数组中只出现一次的数
- 1-1000放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次
- 查找数组重复出现数字(2次或者3次)的唯一数
- 关于从list或者数组中随机抽取部分不重复元素的问题探究
- 寻找数组中只出现一次的数
- 一个整型数组里除了一个或者两个或者三个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)
- 位图法寻找数组中重复出现的数字
- 1-1000放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次,要求速度尽可能的快
- 寻找数组中只出现一次的数
- 【算法】寻找数组中出现的唯一重复的一个数
- 编程之美 N个正整数的数组 寻找丢失的数 和 寻找唯一重复的数
- 找出数组中重复的元素,或者丢失的元素,前提,数组长度N,元素为1到N
- [LeetCode136]Single Number寻找一个数组里只出现一次的数
- 1-1000放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次
- 求数组中出现次数超过一半的元素(《编程之美》寻找水贴王问题)C代码
- 给android avd 安装apk时出现的错误:adb不是内部或者外部指令及丢失adbwinapi.dll问题
- 一个整型数组里除了一个或者两个或者三个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)
- CentOS minimal安装后出现的各种模块丢失问题汇总
- 从一堆(大量的)无序不重复数组成的数组中寻找一指定数出现的位置