以另一种位图的思想来解决一道OJ题目

来源:本站
导读:目前正在解读《以另一种位图的思想来解决一道OJ题目》的相关信息,《以另一种位图的思想来解决一道OJ题目》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《以另一种位图的思想来解决一道OJ题目》的详细说明。
简介:以前所接触到的位图的思想都是以1位的形式去存储某个数出现的次数是1次还是0次。常见的例子不外乎在《编程珠玑》上的开篇例子里,1千万个数的排序统计,用1.25M的内存空间就可以达到遍历一遍输入数据而排序好的目的。这种思想是通用的么?也就是说,假如输入数据不再是0次或者1次,而是2次或者更多的时候,如何再次用上这种思想呢?请看下面题目

题目:

输入一个数组,数组有int类型整数若干,若有其中一个是出现一次或者两次,其他数字都是出现3次,要求在时间复杂度在O(N)上限里求出那个数字。

解法一

生搬硬套位图的思想,既然最多出现3次,那么我用两个bit位来存储一个数出现的个数。那么假如输入是2千万个数的时候,所需要的空间是2.5M。20亿个数的时候,需要的是250M。显然,这种思想还是不太好,虽然符合题目要求。像这样处理海量数据肯定是要被毙掉的。可以尝试着做改进,改进思路是分批处理,如面对20亿的数据,我只自定义一个1千万数的空间,2.5M,然后每次只是处理1千万的数,如果没有出现目标数,那么再处理下一个一千万的数(按照大小区分范围)。应该也算得上一种尚可的思路。

解法二

基于位图思想的变形,我用32个数来存储所有的数中0~31位出现的个数,然后对3取余,如果是2,证明这个数的某一个位出现过2次,依次从0位推到31位。最后相或即可。

这种解法只用到了32 * 32 bit的空间,至于时间,因为需要对每个位进行统计,需要遍历输入数据32次, 32* N,可依然是符合题目的O(N)要求。

这种解法,在时间上应该是要比解法一耗时少一些。第一种解法需要遍历数据约210次,因为int类型最大值是21亿(假如不包括负数),那么就是210个1千万数了。

空间也少很多。无疑是比较好的。

public static int singleNumber(int[] A) {       int[] bitNum = new int[32];       int values = 0;       boolean twiceFlag = false;       for(int i=0;i<32;i++){           for(int j=0;j<A.length;j++){              bitNum[i] += A[j]>>i&1;           }           values |= (bitNum[i]%3)<<i;           if (!twiceFlag && (bitNum[i]%3)>1) {            twiceFlag = true; //如果出现两次}       }       if(twiceFlag)values >>= 1;       return values;   }

提醒:《以另一种位图的思想来解决一道OJ题目》最后刷新时间 2024-03-14 01:03:10,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《以另一种位图的思想来解决一道OJ题目》该内容的真实性请自行鉴别。