136. 只出现一次的数字-E

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

猜你喜欢

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