LeetCode 136. 只出现一次的数字

136. 只出现一次的数字

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

说明:

你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

示例1:
输入: [2,2,1]
输出: 1
示例2:
输入: [4,1,2,1,2]
输出: 4

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/single-number/
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


  • 1. map映射

思路:

  1. 遍历该数组,根据相同元素出现的次数存储到map中
  2. 遍历map,找到 value == 1 的 key,就是我们需要的值
public static int singleNumber(int[] nums) {
        Map map = new TreeMap<>();
        for (int num : nums) {
            if (!map.containsKey(num)) {
                map.put(num, 1);
            } else {
                map.put(num, map.get(num) + 1);
            }
        }
        for (Integer i : map.keySet()) {
            Integer count = map.get(i);
            if (count == 1) return i;
        }
        return -1;
    }

复杂度分析:

  • 时间复杂度:O(n + m) = O(n), 时间复杂度为两次遍历所用的时间

  • 空间复杂度:O(n), map所需要的空间

  • 2. 排序法

思路:

  1. 先将数组进行排序
  2. 遍历该数组,判断当前元素和下一个元素是否相等,如果不等,返回该数即可,否则继续向下遍历
  3. 如果遍历到最后一个元素还没有找到出现一次的数字,则最后一个元素一定是我们需要的
public static int singleNumber(int[] nums) {
        Arrays.sort(nums);
        for (int i = 0; i < nums.length; i += 2) {
            if (i == nums.length - 1) return nums[i];
            if (nums[i] != nums[i + 1]) return nums[i];
        }
        return -1;
    }

复杂度分析:

  • 时间复杂度:O(n)

  • 空间复杂度:O(1)

  • 3. 异或法

思路:异或:相同为0,不同为1. 异或同一个数两次,原数不变。

使用异或判断是否有相同元素

a ^ a = 0
a ^ 0 = a
public static int singleNumber(int[] nums) {
        int res = nums[0];
        if (nums.length > 1) {
            for (int i = 1; i < nums.length; i++) {
                res = res ^ nums[i];
            }
        }
        return res;
    }

复杂度分析:

  • 时间复杂度:O(n)

  • 空间复杂度:O(1)

  • 4. 数学公式法

2∗(a+b+c)−(a+a+b+b+c)=c

public static int singleNumber(int[] nums) {
        Set set = new TreeSet<>();
        int sum = 0;
        int setSum = 0;
        for (int num : nums) {
            set.add(num);
            sum += num;
        }
        for (Integer i : set) {
            setSum += i;
        }
        return 2 * setSum - sum;
    }

复杂度分析:

  • 时间复杂度:O(n + s)

  • 空间复杂度:O(n)

  • 测试用例

public static void main(String[] args) {
        int[] nums = {2, 2, 1};
        System.out.println(Arrays.toString(nums));
        System.out.println("只出现一次的数字:" + singleNumber2(nums));
    }
  • 结果

[2, 2, 1]
只出现一次的数字:1

  • 源码

  • 我会每天更新新的算法,并尽可能尝试不同解法,如果发现问题请指正
  • Github

你可能感兴趣的:(LeetCode 136. 只出现一次的数字)