comments: true
difficulty: 中等
edit_url: https://github.com/doocs/leetcode/edit/main/lcof/%E9%9D%A2%E8%AF%95%E9%A2%9856%20-%20II.%20%E6%95%B0%E7%BB%84%E4%B8%AD%E6%95%B0%E5%AD%97%E5%87%BA%E7%8E%B0%E7%9A%84%E6%AC%A1%E6%95%B0%20II/README.md
面试题 56 - II. 数组中数字出现的次数 II
题目描述
在一个数组 nums
中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。
示例 1:
输入:nums = [3,4,3,3] 输出:4
示例 2:
输入:nums = [9,1,7,9,7,9,7] 输出:1
限制:
1 <= nums.length <= 10000
1 <= nums[i] < 2^31
解法
方法一:位运算
我们用一个长度为 32 的数组 c n t cnt cnt 来统计所有数字的每一位中 1 1 1 的出现次数。如果某一位的 1 1 1 的出现次数能被 3 3 3 整除,那么那个只出现一次的数字二进制表示中对应的那一位也是 0 0 0【说明一定不属于非重复数字的位】;否则,那个只出现一次的数字二进制表示中对应的那一位是 1 1 1。
时间复杂度 O ( n × C ) O(n \times C) O(n×C),空间复杂度 O ( C ) O(C) O(C)。其中 n n n 是数组的长度;而 C C C 是整数的位数,本题中 C = 32 C=32 C=32。
【LeetCode刷题力扣题解 | 剑指Offer56 - II. 数组中数字出现的次数 II | 画图算法思路讲解及C++代码实现】 https://www.bilibili.com/video/BV1ZP4y1x7N3/?share_source=copy_web&vd_source=ed4a51d52f6e5c9a2cb7def6fa64ad6a
核心:重复数字对应为1的位 的个数统计一定为2的倍数。如果不是,就说明 非重复数字 在该位为1。
Python3
class Solution:
def singleNumber(self, nums: List[int]) -> int:
cnt = [0] * 32
for x in nums:
for i in range(32):
cnt[i] += x & 1
x >>= 1
return sum(1 << i for i in range(32) if cnt[i] % 3)
Java
class Solution {
public int singleNumber(int[] nums) {
int[] cnt = new int[32];
for (int x : nums) {
for (int i = 0; i < 32; ++i) {
cnt[i] += x & 1;
x >>= 1;
}
}
int ans = 0;
for (int i = 0; i < 32; ++i) {
if (cnt[i] % 3 == 1) {
ans |= 1 << i;
}
}
return ans;
}
}
C++
class Solution {
public:
int singleNumber(vector<int>& nums) {
int cnt[32]{};
for (int& x : nums) {
for (int i = 0; i < 32; ++i) {
cnt[i] += x & 1;
x >>= 1;
}
}
int ans = 0;
for (int i = 0; i < 32; ++i) {
if (cnt[i] % 3) {
ans |= 1 << i;
}
}
return ans;
}
};
Go
func singleNumber(nums []int) (ans int) {
cnt := [32]int{}
for _, x := range nums {
for i := range cnt {
cnt[i] += x & 1
x >>= 1
}
}
for i, v := range cnt {
if v%3 == 1 {
ans |= 1 << i
}
}
return
}
Rust
impl Solution {
pub fn single_number(nums: Vec<i32>) -> i32 {
let mut counts = [0; 32];
for num in nums.iter() {
for i in 0..32 {
counts[i] += (num >> i) & 1;
}
}
let mut res = 0;
for count in counts.iter().rev() {
res <<= 1;
res |= count % 3;
}
res
}
}
JavaScript
/**
* @param {number[]} nums
* @return {number}
*/
var singleNumber = function (nums) {
const cnt = new Array(32).fill(0);
for (let x of nums) {
for (let i = 0; i < 32; ++i) {
cnt[i] += x & 1;
x >>= 1;
}
}
let ans = 0;
for (let i = 0; i < 32; ++i) {
if (cnt[i] % 3) {
ans |= 1 << i;
}
}
return ans;
};
C#
public class Solution {
public int SingleNumber(int[] nums) {
int[] cnt = new int[32];
foreach(int x in nums) {
int v = x;
for (int i = 0; i < 32; ++i) {
cnt[i] += v & 1;
v >>= 1;
}
}
int ans = 0;
for (int i = 0; i < 32; ++i) {
if (cnt[i] % 3 == 1) {
ans |= 1 << i;
}
}
return ans;
}
}
Swift
class Solution {
func singleNumber(_ nums: [Int]) -> Int {
var bitCounts = [Int](repeating: 0, count: 32)
for num in nums {
var x = num
for i in 0..<32 {
bitCounts[i] += x & 1
x >>= 1
}
}
var result = 0
for i in 0..<32 {
if bitCounts[i] % 3 == 1 {
result |= 1 << i
}
}
return result
}
}