数据结构与算法-只出现一次的元素

Posted by 周思进 on October 3, 2019

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/single-number

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

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

示例 1:

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

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


方法一、循环遍历法

这个一开始思路不对,想的是取一个数,然后循环遍历是否有重复的数,有的话就继续取下一个数进行遍历判断,但问题是后面取的数其实前面有判断过了,所以二层遍历的下标取值应该仍旧从0开始,那遍历就可能和自己进行判断,所以换成判断出现次数只有一次的就是所要找的元素。

int singleNumber(int* nums, int numsSize){
	int i = 0;
	int j = 0;
	int res = 0;
	int cnt = 0;

	for (i = 0; i < numsSize; i++)
	{
		res = nums[i];
		cnt = 0;
		for (j = 0; j< numsSize; j++)
		{
			if (res == nums[j])
				cnt++;
		}

		if (cnt == 1)
			break;
	}

	return res;
}

方法二、异或方式

这个方法主要是了解位的异或运算,简单说就是相同的值进行异或操作等于0,不同的值进行异或操作等于1,所以2个相同的数进行异或操作就是等于0。

0和0异或因为操作数相同,所以结果等于0;0和1异或因为操作数不同所以结果值等于1,可以看出来0和别的值进行异或操作就是那个值,所以此题中相同的2个数最终异或操作完结果等于0,而0和最后那个数异或结果就是那个数。

int singleNumber(int* nums, int numsSize){
	int res = 0;
    
    while (numsSize--)
        res = res ^ nums[numsSize];
    
    return res;
}

其他解题方法
1、列表操作
将元素加入到列表中,下一个元素判断是否已在列表中,如果存在,则将列表中的该元素删除, 如果不存在则加入到列表,这样最终列表剩下的那个就是所要的值。

2、哈希表

3、数学方法
遍历一遍,获取不重复的数,这些数相加乘以2,减去原有数组的数就是所要的值。

4、排序法
将数组排序后,遍历数组,只要该数和前后2个数都不一样,那就是所要的值。