版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/scylhy/article/details/87886113
136. 只出现一次的数字-E
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?(找到的答案,包括clean code book上最优的是o(1)这个算不用额外空间么?)
示例 1:
输入: [2,2,1]
输出: 1
示例 2:
输入: [4,1,2,1,2]
输出: 4
- 分析
一上来,先想的是hash,用数组构建了直接映射,但可能有负数,所以开了两个hash;
后来看解析,可以用map,但是时间复杂应该高点,但java用的hashmap,go map的底层使用hash实现的,故时间复杂度也是ok的;
接着是set,可以移除已经存在的,那么,最后剩下的就是所求;
最后,使用xor所有数据,那么所有偶数都会为0,只剩下单个的那个数;当然,不用第三个数交换两个int,也可以用xor实现。
关于那个不使用额外空间,我想仅遍历数据就需要循环控制,所以不用额外变量是不可能的,故我猜测所谓的不用额外空间,是指o(1)
不像交换两个变量那道题,其要求是不使用第三个变量,而不是不使用额外空间,所以猜测应该是对的 - code
package main
import "fmt"
func singleNumber1(nums []int) int {
a:=make([]int,1000)
b:=make([]int,1000)
for _,j:=range nums{
if j>0{
a[j]++
}else{
b[-j]++
}
}
for i:=0;i<1000;i++{
if a[i]==1{
return i
}else if b[i]==1{
return -i
}
}
return 0
}
//hashmap
func singleNumber2(nums []int)int{
sn:=make(map[int]int)
for _,j:=range nums{
sn[j]++
}
for _,j:=range nums{
if sn[j]==1{
return j
}
}
return 0
}
//set
func singleNumber3(nums []int)int{
sn:=make(map[int]bool)
for _,j:=range nums{
if _,ok:=sn[j];ok{
delete(sn,j)
}else{
sn[j]=true
}
}
for _,j:=range nums{
if _,ok:=sn[j];ok{
return j
}
}
return 0
}
//xor
func singleNumber(nums []int)int{
var single int
for _,j:=range nums{
single^=j
}
return single
}
func main(){
fmt.Println(singleNumber([]int{2,2,1}))
fmt.Println(singleNumber([]int{4,1,2,1,2}))
}