美文网首页
只出现一次的数字 III

只出现一次的数字 III

作者: 7赢月 | 来源:发表于2020-10-24 10:05 被阅读0次

    这个还是有点难搞,许久不曾写算法了,还是有点慢了,持续了半个小时左右,并且使用了goland调式


    package main
    
    func singleNumber(nums []int) []int {
        if len(nums) == 0 {
            return []int{}
        }
        var mid int
        for _, v := range nums {
            mid ^= v
        }
        // 获取非0的第一位
        singleNum := mid & (^mid + 1)
        if singleNum == 0 {
            return []int{mid}
        }
        // 分成两组
        var r1, r2 int
        for _, v := range nums {
            if singleNum&v != 0 {
                r1 ^= v
            } else {
                r2 ^= v
            }
        }
        return []int{r1, r2}
    }
    
    

    思路

    验证只出现一次的两个数字,首先还是使用异或的方法,先获取唯一的数,此时的这个数是两个目标数的异或,因为其他数都出现了两次,这个也很好理解是吧。
    接着就是怎么把这些数分开的问题了,方法也很简单,使用上一步得出的结果,从低位到高位,找到第一个非0的位(先叫它非0位数),这意味着什么,这意味着原始数字可以在非0位数下,分成两组,巧妙,巧妙,大家细细品,看看是不是这样。
    最后,对每组数进行分别异或,就可以得出来那两个只出现一次的数了。

    中间有个小点,我觉得是值得拿出来说说的,就是如何获取非0位数,这个获取的方法有很多。我可以想到的有两种

    • 遍历 这个需要注意边界
    • 计算 这个就是让我很欣喜若狂的点singleNum := mid & (^mid + 1)

    显然,在计算方式下,可以直接获取到我们的非0位数

    相关文章

      网友评论

          本文标题:只出现一次的数字 III

          本文链接:https://www.haomeiwen.com/subject/usjimktx.html