[LeetCode]136. Single Number

136. Single Number

一、题目

Problem Description:
Given a non-empty array of integers nums, every element appears twice except for one. Find that single one.

Follow up:
Could you implement a solution with a linear runtime complexity and without using extra memory?

Example 1:
Input: nums = [2,2,1]
Output: 1

Example 2:
Input: nums = [4,1,2,1,2]
Output: 4

Example 3:
Input: nums = [1]
Output: 1

Constraints:
1 < = n u m s . l e n g t h < = 3 ∗ 1 0 4 1 <= nums.length <= 3 * 10^4 1<=nums.length<=3104
− 3 ∗ 1 0 4 < = n u m s [ i ] < = 3 ∗ 1 0 4 -3 * 10^4 <= nums[i] <= 3 * 10^4 3104<=nums[i]<=3104
Each element in the array appears twice except for one element which appears only once.

二、题解

  • 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素都出现两次。输出这个只出现一次的元素。

2.1 Approach #1 : ArrayList

遍历nums数组中的所有元素。如果当前元素在ArrayList中不存在,则将其加入ArrayList;若存在,则将其删除。由题意,“除了某个元素只出现一次以外,其余每个元素都出现两次”可知,最后只剩一个只出现一次的元素,将其输出即可。

Time complexity : O ( 2 n ) O(2^n) O(2n). 遍历nums数组,消耗 O ( n ) O(n) O(n);在遍历各个元素时,都要判断当前元素是否在ArrayList中,即搜索整个ArrayList来查找是否存在重复元素,又需要 O ( n ) O(n) O(n)。在for循环中,两者相乘,时间复杂度一共 O ( 2 n ) O(2^n) O(2n)
Space complexity : O ( n ) O(n) O(n)

public E remove(int index); 按索引删除元素
public boolean remove(Object o); 若有值相同元素,删除第一个

//ArrayList
//Time complexity : O(2^n); Space complexity : O(n)
class Solution {
    public int singleNumber(int[] nums) {
        List<Integer> list = new ArrayList<Integer>();
        for(Integer x : nums){
            if(list.contains(x) == false){
                list.add(x);
            }else{
                list.remove(x);//x为Integer型,删除该元素值
            }
        }
        return list.get(0);
    }
}

2.2 Approach #2 : Hash Table

思路和 Approach #1 : ArrayList 一致,只是考虑到理想情况下,HashSet / HashMap 的增、删、改、查等操作的时间复杂度都为 O ( 1 ) O(1) O(1),减少了在集合中搜索重复元素的时间复杂度。

以下以HashSet集合为例,HashMap也同理。

Time complexity : O ( n ) O(n) O(n). 遍历nums数组,消耗 O ( n ) O(n) O(n);在遍历各个元素时,都要判断当前元素是否在HashSet中,理想情况下,HashSet的增、删、改、查等操作的时间复杂度都为 O ( 1 ) O(1) O(1)。在for循环中,两者相乘,时间复杂度一共 O ( n ) O(n) O(n)
Space complexity : O ( n ) O(n) O(n)

//Hash Table
//Time complexity : O(n); Space complexity : O(n)
class Solution {
    public int singleNumber(int[] nums) {
        Set<Integer> s = new HashSet<Integer>();
        for(Integer x : nums){
            if(s.contains(x) == false){
                s.add(x);
            }else{
                s.remove(x);
            }
        }
        //经以上操作后,虽然HashSet中只有一个元素,但由于HashSet无索引,故可采取以下方法
        for(Integer x : s){
            return x;
        }
        return 0;
    }
}

2.3 Approach #3 : Math + Hash Table

2 ∗ ( a + b + c ) − ( a + a + b + b + c ) = c 2*(a+b+c)−(a+a+b+b+c)=c 2(a+b+c)(a+a+b+b+c)=c
纯碎的数学思维解题,直接看公式就能理解此方法的思路。

将每次遍历的元素相加,得到 ( a + a + b + b + c ) (a+a+b+b+c) (a+a+b+b+c)
通过HashSet集合判断是否是重复元素,可计算出 ( a + b + c ) (a+b+c) (a+b+c)
最后通过公式: 2 ∗ ( a + b + c ) − ( a + a + b + b + c ) = c 2*(a+b+c)−(a+a+b+b+c)=c 2(a+b+c)(a+a+b+b+c)=c,即可得到所求结果。

Time complexity : O ( n ) O(n) O(n)
Space complexity : O ( n ) O(n) O(n)

//Math + Hash Table
//2*(a+b+c)−(a+a+b+b+c)=c
//Time complexity : O(n); Space complexity : O(n)
class Solution {
    public int singleNumber(int[] nums) {
        Set<Integer> s = new HashSet<Integer>();
        int sumOfSet = 0;
        int sumOfNums = 0;
        for(Integer x : nums){
            if(s.contains(x) == false){
                s.add(x);
                sumOfSet += x;
            }
            sumOfNums += x;
        }
        return 2 * sumOfSet - sumOfNums;
    }
}

2.4 Approach #4 : Bit Manipulation (XOR)

Could you implement a solution with a linear runtime complexity and without using extra memory?
要求不能使辅助空间,并且时间复杂度只能是线性的。

every element appears twice except for one
只有一个数字出现一次,其余数字都出现两次。想到了异或运算的性质:① 任意数字异或其本身都等于0② 任意元素异或0结果为其本身。也就是说,异或数组中的每一个元素,那么最终的结果正是只出现一次的数字,因为其他出现两次的数字在异或其本身时结果都为0。

If we take XOR of zero and some bit, it will return that bit.
a ⊕ 0 = a a⊕0=a a0=a
If we take XOR of two same bits, it will return 0.
a ⊕ a = 0 a⊕a=0 aa=0
a ⊕ b ⊕ a = ( a ⊕ a ) ⊕ b = 0 ⊕ b = b a⊕b⊕a=(a⊕a)⊕b=0⊕b=b aba=(aa)b=0b=b

Time complexity : O ( n ) O(n) O(n)
Space complexity : O ( 1 ) O(1) O(1)

//Bit Manipulation (XOR)
//Time complexity : O(n); Space complexity : O(1)
class Solution {
    public int singleNumber(int[] nums) {
        int res = 0;
        for(int x : nums){
            res ^= x;
        }
        return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值