剑指offer_56_数组中唯一只出现一次的数字II【javascript】

46 阅读1分钟

题目链接

leetcode.cn/problems/sh…

题目

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

示例

示例 1:
输入:actions = [5, 7, 5, 5]
输出:7

示例 2:
输入:actions = [12, 1, 6, 12, 6, 12, 6]
输出:1

提示:

  • 1 <= actions.length <= 10000
  • 1 <= actions[i] < 2^31

题解

有限状态自动机

  • 时间复杂度 O(N)
  • 空间复杂度 O(1)
/**
 * @param {number[]} actions
 * @return {number}
 */
var trainingPlan = function(actions) {
    let ones = 0, twos = 0;
    for(let action of actions){
        ones = ones ^ action & ~twos;
        twos = twos ^ action & ~ones;
    }
    return ones;
};

遍历统计

  • 时间复杂度 O(N)
  • 空间复杂度 O(1)
/**
 * @param {number[]} actions
 * @return {number}
 */
var trainingPlan = function(actions) {
    let counts = new Array(32).fill(0);
    for(let action of actions) {
        for(let i = 0; i < 32; i++) {
            counts[i] += action & 1; // 更新第 i 位 1 的个数之和
            action >>= 1;            // 第 i 位 --> 第 i 位
        }
    }
    let res = 0, m = 3;
    for(let i = 31; i >= 0; i--) {
        res <<= 1;
        res |= counts[i] % m;        // 恢复第 i 位
    }
    return res;
};

位运算

/**
 * @param {number[]} actions
 * @return {number}
 */
var trainingPlan = function(actions) {
    let res = 0;
    for (let i = 0; i < 32; i++) {
        let cnt = 0;
        let bit = 1 << i;
        for (let j = 0; j < actions.length; j++) {
            if (actions[j] & bit) cnt++;
        }
        if (cnt % 3 != 0) res = res | bit;
    }
    return res;
};