位运算/260只出现一次的数字

给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。 利用除答案以外的元素均出现两次,我们可以先对 nums 中的所有元素执行异或操作,得到 sum,sum 为两答案的异或值(sum 必然不为 0)。

然后取 sum 二进制表示中为 1 的任意一位 k,sumsum 中的第 k 位为 1 意味着两答案的第 k 位二进制表示不同。

对 nums 进行遍历,对第 k 位分别为 0 和 1 的元素分别求异或和(两答案必然会被分到不同的组),即为答案。

代码来源:宫水三叶力扣

class Solution {
    public int[] singleNumber(int[] nums) {
        int sum = 0;
        for (int i : nums) sum ^= i;
        int k = -1;
        //i=31 因为最多是32
        for (int i = 31; i >= 0 && k == -1; i--) {
            if (((sum >> i) & 1) == 1) k = i; //if条件,用来确认当前位是否为1
            //k用来保存从哪个位开始有1(即最高位有1 而当k!=-1时,此for循环会推出)
        }
        int[] ans = new int[2];
        for (int i : nums) {
            //对应之前的理论,此第k位,必定一个是0一个是1,否则不可能出现异或等于1 的情况
            //而两个元素必然会分到不同的组中,只需要在两个组中分别求异或和即可
            //而对于其他出现两次的干扰元素,因为是出现了两次,因此他们的异或和必然为0
            if (((i >> k) & 1) == 1) ans[1] ^= i;
            else ans[0] ^= i;
        }
        return ans;
    }
}
上一篇:TypeError: write() argument must be str, not list


下一篇:商业电子邮件诈骗损失已达260亿美元!如何在遭受欺诈后快速施救?