[剣はオファーを指します] 56.2配列内の数字の出現回数

タイトル説明

ここに画像の説明を挿入します

// 56.2 数组中数字出现的次数

// 力扣
// 在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现
// 了三次。请找出那个只出现一次的数字。

回答

// 力扣
// 在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次
// 。请找出那个只出现一次的数字。

// 创建计数数组count,记录所有nums元素在二进制表示下每一位出现1的次数
// 比如count[0]就是nums所有元素在最低位出现1的次数。
// 
// 一个双for循环,第一个for遍历nums的元素num,第二个for遍历计数数组索引j,
// 也就是从低到高遍历num的每一位二进制位。
// 如果num & 1为1,则当前逻辑运算结果1累加到count[j]中,然后
// num整体右移1一格num = num >>> 1,j也右移一位,即开始遍历下一位
// 二进制位,再和1做逻辑与,如此循环。第二层for循环走一轮能找出一个num的
// 所有位出现1的次数,并记录到count的相应位置中。
// 两个for循环之后,能把所有nums的元素的所有位出现的1累计到count的相应位置

// 第二个for循环,倒序遍历count,索引为i,索引的计数元素为count[i],
// 由于需要找出的目标元素target出现了1次,其他元素都出现了3次,
// 所以其他元素对应的二进制位出现1的次数一定是3的倍数,如果该位出现
// 1的次数不是3的倍数,无法整除3,说明该位一定出现了target的1。我们将
// 余数或逻辑运算赋给变量res中,然后res左移,i左移,如此循环,可以把
// count中所有位中属于target的二进制1赋给res,使得res等于target。
// 最后返回res即可。

// 执行用时:5 ms, 在所有 Java 提交中击败了85.82%的用户
// 内存消耗:39.3 MB, 在所有 Java 提交中击败了73.60%的用户
class Solution {
    public int singleNumber(int[] nums) {
        int[] count = new int[32];
		for (int num : nums) {
			for (int j = 0; j < count.length; j++) {
				count[j] += num & 1;
				num >>>= 1;
			}
		}
		int res = 0, three = 3;
		for (int i = count.length - 1; i >= 0; i--) {
			res <<= 1;
			res |= count[i] % three;
		}
		return res;
    }
}

おすすめ

転載: blog.csdn.net/fisherish/article/details/114884215