版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/scylhy/article/details/87889396
137. 只出现一次的数字 II-M
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,3,2]
输出: 3
示例 2:
输入: [0,1,0,1,0,1,99]
输出: 99
-
分析
除一个数出现一次,其他数都出现3次下,挑出出现一次的数;
这里用到了Single Number 1中的XOR,以及用来清除数据的&^;
另外,可以用位ith的累加mod 3挑出支出一次的数,该方法好理解且使用其他类型题如一个数出现m次,其他数出现n次,可以很快用该方法解决,但要是用为计算那就得尝试半天了。 -
code
package main
import "fmt"
func singleNumber1(nums []int)int{
var c [64]int
var single int
var k uint
for _,j:=range nums{
for k=0;k<64;k++{
c[k]+=1&(j>>k)
}
}
for k=0;k<64;k++{
single|=c[k]%3<<k
}
return single
}
func singleNumber2(nums []int)int{
var ones,twos,three int
for _,j:=range nums{
twos|=ones&j
//ones&j保证ones为0是,two不会记录j,
//ones记录一次时,j若是第2次,则记录,若不是,则不记录;
//同时|保证不会清理掉已有的信息
ones^=j
three=twos&ones
//three是个临时数据,只记录出现第三次的那个数
ones&=^three
twos&=^three
//出现三次时,ones、twos、three同时含有一个数的信息,可以用three清理掉该数,
//若不是第三次,则^three全1不会对ones、twos产生影响
}
return ones //最后ones中只剩下一个
}
func singleNumber(nums []int)int{
var ones,twos int
for _,j:=range nums{
ones=(ones^j)&^twos
twos=(twos^j)&^ones
//&^可易用来清理偶数出现的,保留奇数次数出现的
}
return ones //最后ones中只剩下一个
}
func main(){
fmt.Println(singleNumber([]int{2,2,2,1}))
fmt.Println(singleNumber([]int{4,1,1,2,2,1,2}))
}