LeetCode -- 数字出现的次数类

problem1

1. 题目描述

一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。



2. 思路

找一个不同点,将所有数字分为两类。
其中,两个只出现一次的数字各出现在一个集合当中。
如何找最后一个不同点?
我们知道,如果两个数字不同的话,那么,在二进制表示下,他们一定有一个二进制位是不同的,其中一个为 \(0\),一个为 \(1\)
通过对所有数字求异或和,就可以得到 \(a\) ^ \(b\),然后枚举一下,任意找一个不同点即可!



3. 代码

class Solution {
public:
    vector<int> singleNumbers(vector<int>& nums) {
        int xors = 0;  
        for(auto &x : nums) xors ^= x;
        int diff = 0; // 二进制表示中第一个不同点
        for(int i = 0; i < 32; i ++ ) {
            if(xors >> i & 1) {
                diff = i;
                break;
            }
        }
        int r1 = 0, r2 = 0;
        for(auto &x : nums) {
            if(x >> diff & 1)   r1 ^= x;
            else    r2 ^= x;
        }
        return {r1, r2};
    }
};



problem2

1. 题目描述

一个数字出现了一次,其余都出现了三次



2. 思路

(1) 卡诺图

卡诺图做法,然而我不太懂卡诺图。。

class Solution {
    public int singleNumber(int[] nums) {
        // 可以设计一种逻辑,使数字出现 3 次时,该逻辑的结果为 0(即只有 0,1,2 三种状态)
        // 其实就是一个 三进制
        // 一位二进制数只能存储 0 和 1 两种状态,所以我们需要用到两位二进制
        // 设两位二进制数的高位为 A,低位为 B。C 是输入变量
        // 表示的三种情况为 : 0次:00(A=0,B=0), 1次:01(A=0,B=1), 2次:10(A=1,B=0) 
        // 注:11(A=1,B=1) 为无效输入

        // 画出关于 A 的卡诺图(AB为11的结果是不重要的,用 x 表示):
        //  AB\C |  0  |  1
        //  =================
        //    00 |  0  |  0
        //    01 |  0  |  1        ====> 得到 A = BC + AC'
        //    11 |  x  |  x
        //    10 |  1  |  0

        //  画出关于 B 的卡诺图
        //  AB\C |  0  |  1
        //  =================
        //    00 |  0  |  1
        //    01 |  1  |  0        ====> 得到 B = BC' + A'B'C
        //    11 |  x  |  x
        //    10 |  0  |  0

        // 很明显啊,我们需要的就是只出现一次的情况 01(A=0,B=1),即 B 的结果
        int A = 0, B = 0;
        for (int C : nums) {
            int tmp = A;
            A = (B & C) | (A & ~C);
            B = (B & ~C) | (~tmp & ~B & C);
        }
        return B;
    }
}

(2)状态机

ref



problem3

1. 题目描述



2. 思路



3. 代码



problem4

1. 题目描述



2. 思路



3. 代码



posted @ 2023-03-06 13:07  光風霽月  阅读(10)  评论(0编辑  收藏  举报