leetcode【260】Single Number III

写在最前面:

当然可以通过遍历查找,但是时间复杂度太高,leetcode肯定通不过。

然后我们要研究异或。

 

leetcode【260】Single Number III


Given an array of numbers nums, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once.

Example:

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

Note:

  1. The order of the result is not important. So in the above example, [5, 3] is also correct.
  2. Your algorithm should run in linear runtime complexity. Could you implement it using only constant space complexity?

首先给出很常规的解法: 

class Solution(object):
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        length = len(nums)
        res = []
        newnum = []
        for i in range(length):
            for j in range(i+1,length):
                if nums[i] == nums[j]:
                    res.append(nums[j])
            if nums[i] not in res:
                newnum.append(nums[i])
        return newnum

 

借鉴一下大神的思路吧,前方高能!

关键思路是,只有两个数不同,那么我们需要一遍异或,这个异或的值是什么呢,是两个不同的数的异或值,然后我们用mark标记这这个异或值其中哪一位是1,因为这个异或值只有两个1,这两个1区分了不同的两个数。假设3,5是不同的数,异或为6,即0110,那么我们就可以拿0100和0010去遍历所有数,进行与操作,与操作的规则是只有两个都为1,结果才为1,其余都是0。只要遍历结果为0000,即为0,那么我们就找到了这个数。

而大神的代码效率高在于他找到第一个为1的数,即0010后,没有再找下一个,那么这个0010遍历所有数后只能找到一个不同的数,神奇的在于,除去一个不同的数,假设是3,那么剩下所有的数相异或的结果就是另一个不同的数,5!

class Solution(object):
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        xor = 0
        num1, num2 = 0, 0
        for num in nums:
            xor ^= num
        mask = 1
        while xor & mask == 0:
            mask = mask << 1
        for num in nums:
            if num & mask == 0:
                num1 ^= num
            else:
                num2 ^= num
        return [num1, num2]

 

下面是我理解了思路自己写的,即使关键部分用了异或和与运算,还是在leetcode上超时。 主要是因为我找到两个mark,分别去遍历所有数,导致时间复杂度高。

class Solution(object):
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        xor = 0
        num1, num2 = 0, 0
        if len(nums) == 2:
            return nums
        for num in nums:
            xor ^= num
        mask1 = 1
        while xor & mask1 == 0:
            mask1 = mask1 << 1
        
        mask2 = mask1 << 1

        while xor & mask2 == 0:
            mask2 = mask2 << 1

        for num in nums:
            if num & mask1 == 0:
                num1 ^= num
        
            elif num & mask2 == 0:
                num2 ^= num
        return [num1, num2]

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值