zoukankan      html  css  js  c++  java
  • 【LeetCode每天一题】Single Number II(数组中单个数字II)

    Given a non-empty array of integers, every element appears three times except for one, which appears exactly once. Find that single one.

    Note:

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

    Example 1:

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

    Example 2:

    Input: [0,1,0,1,0,1,99]
    Output: 99

    思路

      之前那道题中是数组中相同的数字个数为2个,因此我们可以根据异或的性质来解决。但是这道题中数组中相同的数字个数为3个,不能根据利用异或进行解决了。但是我们可以使用位运算的思想,大概的方法就是我们先申请一个长度为32的辅助数组(假设最大范围是232次方),辅助数组中每一位代表数组中所有数字的二进制对应位置1的数量,当我们对所有数组统计完毕之后,因为除了一个数字之外,其他所有数字都出现了三次。我们对辅助数组中每一位对3取余,最后得到的就是出现一个数字的结果。时间复杂度位O(n),空间复杂度位O(1)。
      另外还有一个比较有意思的答案,就是既然除了一个数字出现一次之外,其他的数字都想出现了三次,我们可以利用python 中集合的特性,先将数组转化为集合,去除重复的数字。然后用得到的集合求和并乘以3在减去原数组求的和,这时得到的结果就是出现了一次的数字*2。最后将结果除以2得到结果。时间复杂度为O(n),空间复杂度为O(n)。
    解决代码

    第一种思路
     1 class Solution(object):
     2     def singleNumber(self, A):
     3         ans = 0
     4         for i in range(32):     # 从第一位开始统计
     5             count = 0
     6             for a in A:           # 统计当前位1的个数。
     7                 if ((a >> i) & 1):     
     8                     count+=1
     9             ans |= ((count%3) << i)  # 添加进结果中
    10         if ans >= 2**31:        # 应对负数的异常情况
    11             ans -= 2**32
    12         return ans
    第二种思路
    1 class Solution(object):
    2     def singleNumber(self, A):
    3         nums_set = set(nums)       # 转化为集合
    4         res2 = sum(nums_set)*3 - sum(nums) # 相减
    5         res = res2/2       # 除以2 得到结果
    6         return res
  • 相关阅读:
    Linux 安装Zookeeper<集群版>(使用Mac远程访问)
    04寻找两个数组的中位数
    28实现strSTR()
    125验证回文串
    124,二叉树中的最大路径和
    123买卖股票的最佳时机III
    02爬取豆瓣最受欢迎的250部电影
    01爬取当当网500本五星好评书籍
    112买卖股票的最佳时机II
    121.买卖股票的最佳时机
  • 原文地址:https://www.cnblogs.com/GoodRnne/p/10931669.html
Copyright © 2011-2022 走看看