这一系列时间复杂度均要求只出现了一次的数字系列 - 图1,空间复杂度均要求只出现了一次的数字系列 - 图2,所以不适用哈希表的方式

问题一

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
示例:
输入: [4,1,2,1,2]
输出: 4

思路: 只出现了一次的数字系列 - 图3(异或)运算(相同为0,不同为1)可以用来找到两个数字二进制之间的差异,如果两个数字相同进行异或结果为0,否则不为零,只出现了一次的数字系列 - 图4。异或满足交换律。那么这题只要所有的数进行只出现了一次的数字系列 - 图5运算,结果就是只出现一次的数。
可推广为数字中,某个元素出现了奇数次,其它元素均出现偶数次,找出出现奇数次的元素。
代码:

  1. impl Solution {
  2. pub fn single_number(nums: Vec<i32>) -> i32 {
  3. nums.iter().fold(0, |acc, e| acc ^ e)
  4. }
  5. }

问题二

给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。
示例:
输入: [1,2,1,3,2,5]
输出: [3,5]

思路:类似问题一,如果我们将所有数异或一遍,结果应该是那两个只出现一次的元素设为只出现了一次的数字系列 - 图6的异或结果只出现了一次的数字系列 - 图7。那么只出现了一次的数字系列 - 图8表示只出现了一次的数字系列 - 图9二进制之间的差异。公式 只出现了一次的数字系列 - 图10结果是只保留 只出现了一次的数字系列 - 图11二进制的最后一位 1。所以只出现了一次的数字系列 - 图12的结果(设为变量 只出现了一次的数字系列 - 图13)就是只出现了一次的数字系列 - 图14二进制的最后一位差异。那么 只出现了一次的数字系列 - 图15 或者

只出现了一次的数字系列 - 图16,我们据此可以分辨出 只出现了一次的数字系列 - 图17,让只出现了一次的数字系列 - 图18与其它出现两次的元素异或,那么就变成只有一个出现一次元素的问题了。结果就是只出现了一次的数字系列 - 图19。则 只出现了一次的数字系列 - 图20
可推广为数字中,某两个元素出现了奇数次,其它元素均出现偶数次,找出出现奇数次的元素。
结合以下代码就很清楚了:

pub fn single_number(nums: Vec<i32>) -> Vec<i32> {
    let mut mask = 0;
    for num in &nums {
        mask ^= num;
    }

    // 保留最后一位1,这个1要么是x的,要么是y的,假设是x的
    let last_one = mask & (mask * -1);

    let mut x = 0;
    for num in &nums{
        // 过滤掉y,就变成了问题一
        if num & last_one != 0 {
            x ^= num;
        }
    }

    // 找到x, y = mask ^ x
    vec![x, mask ^ x]
}

// impl Solution {
//     pub fn single_number(nums: Vec<i32>) -> Vec<i32> {
//         let mask = nums.iter().fold(0, |acc, n| acc ^ n);
//         let last_one = mask & (mask * -1);
//         let x = nums.iter().filter(|&&n| n & last_one != 0).fold(0, |acc, n| acc ^ n);
//         vec![x, mask ^ x]
//     }
// }

问题三

大神题解
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次。找出那个只出现了一次的元素。
示例:
输入: [0,1,0,1,0,1,99]
输出: 99

思路:

代码: