【剑指offer】数组中只出现一次的数字

    xiaoxiao2025-07-28  20

    思路真的很巧妙。

    为什么要强调剩下的数字都出现了两次,而不是出现多次?

    考虑到每个数字,自己和自己异或结果是0。

    把数组中所有数字做异或,重复出现的数字被消掉了,最后的结果是要求的两个只出现一次的数字的异或值。

    因为要求的这两个只出现一次的数字一定不相同,所以它们的异或值一定有某些位是1。这两个待求的只出现一次的数就是在这一位上有差异。

    于是我们就把看一下这个异或值哪一位有1,再按照这一位把所有的数字分成两拨。

    我们把这两拨数字分别异或,最后得到的两个数字即为所求。因为两个待求数字一定是分在这两拨里面,剩下的数都是成双成对的一定会被消掉。

    class Solution { public: void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) { int len = data.size(); if (len < 2) return; int tmp = 0; for (int i : data) tmp ^= i; int pos = find1Pos(tmp); *num1 = 0, *num2 = 0; for (int i : data) compute(pos, num1, num2, i); } int find1Pos(int t) { int res = 0; while ((( t & 1) == 0) && res < 8*sizeof(int)) { ++res; t = t >> 1; } return res; } void compute(int const pos, int *num1, int *num2, int i) { if (((i >> pos) & 1 )== 0) *num1 ^= i; else *num2 ^= i; } };

    代码写完总也过不去,最后发现是这句出了问题((t & 1) == 0),一开始我写的是t&1==0,因为&的算术优先级低于==所以结果不对。吃一堑长一智!

    最新回复(0)