Given a non-empty array of integers, every element appears three times except for one, which appears exactly once. Find that single one.

    Note:

    Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

    Example 1:

    1. Input: [2,2,3,2]
    2. Output: 3

    Example 2:

    1. Input: [0,1,0,1,0,1,99]
    2. Output: 99

    题意

    给定一个非空数组,该数组中除了一个元素只出现一次外,其余所有元素都出现了三次,找出该元素。

    思路

    1. 使用HashMap标记只出现一次的元素;
    2. 先对数组排序,再找出只出现一次的元素;
    3. 求出数组和sum2以及对应的Set集合的和sum1,则待求元素为 137. Single Number II (M) (待学习) - 图1
    4. 位运算:
      1. 对于int的32位,统计数组中所有数在每一位上“1”的个数,如果正好是3的倍数,说明目标元素x在对应位上为0;如果不是3的倍数,说明x在对应位上为1;
      2. 参考 LeetCode 137. 只出现一次的数字 II

    代码实现 - Map

    1. class Solution {
    2. public int singleNumber(int[] nums) {
    3. Map<Integer, Boolean> map = new HashMap<>();
    4. for (int i = 0; i < nums.length; i++) {
    5. if (map.containsKey(nums[i])) {
    6. map.put(nums[i], true);
    7. } else {
    8. map.put(nums[i], false);
    9. }
    10. }
    11. for (Integer i : map.keySet()) {
    12. if (map.get(i) == false) {
    13. return i;
    14. }
    15. }
    16. return 0;
    17. }
    18. }

    代码实现 - 排序

    1. class Solution {
    2. public int singleNumber(int[] nums) {
    3. Arrays.sort(nums);
    4. for (int i = 0; i < nums.length; i++) {
    5. if (i - 1 < 0 && i + 1 >= nums.length) {
    6. return nums[i];
    7. } else if (i - 1 < 0 && nums[i] != nums[i + 1]) {
    8. return nums[i];
    9. } else if (i + 1 >= nums.length && nums[i] != nums[i - 1]) {
    10. return nums[i];
    11. } else if (i - 1 >= 0 && i + 1 < nums.length && nums[i] != nums[i - 1] && nums[i] != nums[i + 1]) {
    12. return nums[i];
    13. }
    14. }
    15. return 0;
    16. }
    17. }

    代码实现 - Set求和

    1. class Solution {
    2. public int singleNumber(int[] nums) {
    3. long sum1 = 0, sum2 = 0;
    4. Set<Integer> set = new HashSet<>();
    5. for (int i = 0; i < nums.length; i++) {
    6. sum2 += nums[i];
    7. set.add(nums[i]);
    8. }
    9. for (int i : set) {
    10. sum1 += i;
    11. }
    12. return (int) ((sum1 * 3 - sum2) / 2);
    13. }
    14. }

    代码实现 - 位运算 1

    1. class Solution {
    2. public int singleNumber(int[] nums) {
    3. int ans = 0;
    4. for (int i = 0; i < 32; i++) {
    5. int count = 0;
    6. for (int num : nums) {
    7. if (((num >> i) & 1) == 1) {
    8. count++;
    9. }
    10. }
    11. if (count % 3 != 0) {
    12. ans = ans | (1 << i);
    13. }
    14. }
    15. return ans;
    16. }
    17. }

    代码实现 - 位运算 2

    1. class Solution {
    2. public int singleNumber(int[] nums) {
    3. int a = 0, b = 0;
    4. for (int i = 0; i < nums.length; i++) {
    5. a = (a ^ nums[i]) & (~b);
    6. b = (b ^ nums[i]) & (~a);
    7. }
    8. return a;
    9. }
    10. }