• 使用位操作


    见朋友出了问题,最近访问技术论坛时,大致是这样的:有一组。其中包括:N整数,除了的整数只有一次以外,其他已经出现3二级。如何找到只出现一次最快的数?

    作者的解法有点忘记了。可是这个题突然让我想起之前《编程之美》里的一道题, 和这个题的差别是其它都出现2次,仅仅有一个是出现一次。

    它的解法很巧妙。就是把全部整数进行异或运算,最后的结果就是仅仅出现一次的那个整数。由于异或会把相同的消除掉。可是这个题是出现3次。异或已经解决不了。第一想法是空间换时间,全部数中取最大值Max,然后定义一个数组int hashArr[Max],运用hash的思想。遍历全部整数进行hashArr[i]++运算。最后再找出hashArr[i]为1的,下标值就是所求的数。这个解法相同适用于其它出现N次的情况。解法时间复杂度为O(N),空间额外开销为S(MAX)

    可是我们能够继续深入分析。以32bit整数为例。假设把全部数的第i个比特位相加,假如和为sum。则会有例如以下等式:3(x1 + x2 + ... + xn) + x0 = sum (x1代表第一个数的第i个比特位的值 X0代表仅仅出现一次整数的第i个比特位的值) 从这个等式中能够看出x0的值为sum/3的余数。由于x0不是1就是0。肯定小于3。所以我们能够有例如以下的代码:

    int arr[N] = {};
    int _tmain(int argc, _TCHAR* argv[])
    {
    	int nMask = 1;
    	int nBitSum = 0;
    	int nDst = 0;
    	for (int i = 0; i < 32; ++i)	//依次推断32位
    	{
    		for (int j = 0; j < N; ++j)	 //对N个数的第i位求和
    		{
    			if (arr[j] & nMask)
    			{
    				nBitSum++;
    			}
    		}
    
    		if (nBitSum%3 != 0)		//余数不是1就是0
    		{
    			nDst |= nMask;
    		}
    
    		nMask <<= 1;
    		nBitSum = 0;
    	}
    
    	return nDst;
    }


    
    这样就把仅仅出现一次的数求出来了,并且假设其它数出现的次数是M次的话,mod M就能够了。时间复杂度是O(32*N),  空间额外开销就是几个成员变量。
    


    相比較而言还下面的算法是较好,当然,还详细介绍了情况而定。

    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    hdu 3666 差分约束系统
    hdu 1198农田灌溉
    常微分方程(阿諾爾德) Page 45 相空間,相流,運動,相曲線 註記
    高等微積分(高木貞治) 1.4節 例2
    常微分方程(阿諾爾德) Page 45 相空間,相流,運動,相曲線 註記
    解析函數論 Page 29 命題(2) 函數模的有界性
    高等微積分(高木貞治) 1.4節 例2
    解析函數論 Page 29 命題(1) 有界閉集上的一致連續性
    解析函數論 Page 29 命題(3) 模的下界的可達性
    解析函數論 Page 29 命題(2) 函數模的有界性
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4818892.html
Copyright © 2020-2023  润新知