算法_在一个数组中,一个数出现p次(p>=1 && p%k!=0),其他数出现k次(k>1),求出现p次的数

1.数组元素只有1bit进行求解:

  1.令m满足2^{m} \geq k,构建m个1bit宽的计数器$$\overrightarrow {\textup{x}}}$$ = [x_{1}, x_{2}, x_{3}...., x_{m}] ($$x_{i}= 0/1$$),其中x_{i}为1bit单元。carry为进位到当前位的值。

进位 x_{i} 计算后x_{i}
0 0 0
0 1 1
1 0 1
1 1 0

    所以有:

                                          x_{m} = x_{m} \^\ (x_{m-1} \&\ ... \&\ x_{1} \&\ i);

                                         x_{m-1}= x_{m-1} \^\ (x_{m-2} \&\ ... \&\ x_{1} \&\ i);

                                         ......

                                         x_{1} \^\ = x_{1} \^\ i;

 

  2.当计数器m值等于k时,需要将计数器m清零,而不等于k时,无需操作,此时可以如下操作:

k_{j}} x_{j} y_{j}
0 0 0
0 1 1
1 0 1
1 1 0

 

                           当 k_{j} = 1 时y_{j} = x_{j}

可得到公式:

                           当 k_{j} = 0 时y_{j} = \~{} x_{j}

 

 

  令1bit数mark = ~(y_{m} \& y_{m-1}\&...\&y_{1}),然后对计数器m的每一位进行与mark与操作,可以保证当m值等于k时,m置零。

2.数组元素32bit进行求解:

算法_在一个数组中,一个数出现p次(p>=1 && p%k!=0),其他数出现k次(k>1),求出现p次的数_第1张图片

此时可以构建32个m-bit宽的计数器,即将数组元素的每一位作为一个0/1的1bit数组进行求值,可表现为m个32位数,这m个32位数的同一位构成一个m-bit宽的计数器,根据k的数值去构建32位mark,再去判断m-bit宽的计数器是否需要清零。由于第j位bit值处的m-bit宽的计数器中记录的是该位中出现1的次数,所以当出现p次的数组元素的某一位(i)是1,p^{'} = p \% k用二进制表示的1的位置(j)指代的第i个m-bit宽的计数器第j位肯定为1,即当x_{i} \neq 0时,返回值为x_{i}}

 

编辑太费劲、直接上链接: https://leetcode.com/problems/single-number-ii/discuss/43295/Detailed-explanation-and-generalization-of-the-bitwise-operation-method-for-single-numbers

你可能感兴趣的:(算法学习)