leetcode【260】Single Number III

版权声明:本文为博主原创文章,未经允许,不得转载,如需转载请注明出处 https://blog.csdn.net/ssjdoudou/article/details/83931392

写在最前面:

当然可以通过遍历查找,但是时间复杂度太高,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]

猜你喜欢

转载自blog.csdn.net/ssjdoudou/article/details/83931392
今日推荐