[题解][LeetCode][Single Number II]

题目:

Given an array of integers, every element appears three times except for one. Find that single one.

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

题解1:

线性,但是使用额外空间的办法。

python 开一个dict记录每个数字出现的次数,然后扫一遍dict,找到次数为1的并return


Code1:

class Solution:
    # @param A, a list of integer
    # @return an integer
    def singleNumber(self, A):
        d = {'0' : 0}
        for i in A:
        	s = str(i)
        	if s in d :
        		d[s] += 1
        	else :
        		d[s] = 1
        for s in d:
        	if d[s] == 1:
        		return int(s)

        return 0


题解2:

位运算,可以达到线性,并且不使用额外空间(一个用来“遍历‘的变量还是要的...)

思想是,一个数字出现三次,那么按位相加的话,每个位上应该是3。

那么,把所以数字加起来,每个位上mod 3 之后,余1的位,就是只出现1次的那个数字的。


普遍办法是,开一个list,记录每个位的和。但是那样就有额外空间了。

极限办法是,用3个变量,每个变量的每个位分别代表”这个位出现了1次\2次\0次 (mod 3之后)


为了不多用空间,我的代码中:

A[1]的每个位上代表“这个位出现了1次

A[2]的每个位上代表“这个位出现了2次

A[0]的每个位上代表“这个位出现了0次


Code2:

class Solution:
    # @param A, a list of integer
    # @return an integer
    def singleNumber(self, A):
        if len(A) == 1:
            return A[0]
        #Every bit in A[1] means this bit occurs 1 time
        #Every bit in A[2] means this bit occurs 2 times
        #Every bit in A[0] means this bit occurs 3 times(mod 3 == 0)
        i = A[2]
        A[2] = A[1] & i
        A[1] ^= i

        A[2] |= A[1] & A[0]
        A[1] ^= A[0]

        A[0] = A[1] & A[2]
        A[1] &= ~A[0]
        A[2] &= ~A[0]

        for i in A[3:]:
            A[2] |= A[1] & i   #if the bit occurs both in A[1] and the new number, then it occurs 2 times
            A[1] ^= i          
            A[0] = A[1] & A[2] #if it occurred 1 time & 2times, then it occurred 3 times(mod 3 == 0)
            A[1] &= ~A[0]      #if the bit occurred 3 times, then it doesn't belong to A[1],A[2]
            A[2] &= ~A[0]       #which means the bit occurred 1 time and 2 times

        return A[1]


Ps:

因为我借用了list里的A[0] A[1] A[2] , 所以要考虑给的list里只有1个元素的特殊情况


参考:

http://www.acmerblog.com/leetcode-single-number-ii-5394.html


其他类似题目:

1. 每个数字出现两次,只有一个数字出现一次(直接将所有数字进行异或即可,因为相同数字异或得0)

2. 每个数字出现两次,有两个数字只出现一次


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值