137. 只出现一次的数字 II-M

版权声明:本文为博主原创文章,未经博主允许不得转载。 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}))
}

猜你喜欢

转载自blog.csdn.net/scylhy/article/details/87889396