JavaScript 算法练习(二) - 只出现一次的数字

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

说明:

你的算法应该具有线性时间复杂度O(n)。 你可以不使用额外空间来实现吗?

示例 1:

输入: [2,2,1]
输出: 1

示例 2:

输入: [4,1,2,1,2]
输出: 4

方法一:利用Map() Hash 结构

Map真的是解决算法问题的神器…

方法如下

var singleNumber = function(nums) {
	let l = nums.length
	let map = new Map()
	for(let i = 0; i < l; i++) {
    	if (map.has(nums[i])) {
        	map.delete(nums[i])
    	} else {
       		map.set(nums[i], i)
    	}
	}
	return [...map.keys()][0]
};

方法二: 利用 对象或数组

这个本质其实跟Map差不多,以对象为例

var singleNumber = function(nums) {
	let l = nums.length
	let hash = {}
	for(let i = 0; i < l; i++) {
		if (hash[nums[i]] != undefined) {
			delete hash[nums[i]]
		} else {
			hash[nums[i]] = i
		}
	}
	return Object.keys(hash)[0]
};

方法三:利用 indexOf() lastIndexOf()

不过这个费时间比价多,严格来说不算 O(n)复杂度了

var singleNumber = function(nums) {
    let l = nums.length
    let map = new Map()
    for(let i = 0; i < l; i++) {
        if(nums.indexOf(nums[i])==nums.lastIndexOf(nums[i])){
            return nums[i]
        }
    }

};

方法四:异或运算!

看到这个就惊呆了,真的好方便!之前一直不会运用异或。

var singleNumber = function(nums) {
    let l = nums.length
    let val = 0
    for(let i = 0; i < l; i++) {
        val ^= nums[i]
    }
    return val
};

很精简的代码!执行效率也是这几个方法里最高的。

关于异或的运算法则

1)交换律:a ^ b = b ^ a
2)结合律:a ^ b ^ c = a ^ (b ^ c) = (a ^ b) ^ c
3)d = a ^ b ^ c  ==>  a = d ^ b ^ c
4)自反性:a ^ b ^ a = b

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦