一、需求
给你一个 非空 整数数组 nums
,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。
示例 1 :
输入:nums = [2,2,1]
输出:1
示例 2 :
输入:nums = [4,1,2,1,2]
输出:4
示例 3 :
输入:nums = [1]
输出:1
提示:
1 <= nums.length <= 3 * 104
-3 * 104 <= nums[i] <= 3 * 104
- 除了某个元素只出现一次以外,其余每个元素均出现两次。
二、思路分析图
(一)异或破解方案
三、代码
(一)数据初始化/调用函数
/**
* 入口
* 136、只出现一次的数字
* 输入:
* [4,1,2,1,2]
* 输出:
* 4
* 解释:
* 1.暴力破解方案
* 2.异或破解方案
* 3.HashSet方案
*/
@Test
public void suanfa31()
{
// 初始化
int[] nums = { 4, 1, 2, 1, 2 };
// 打印
int a = this.singleNumberViolence(nums);
System.out.println("暴力破解方案 = " + a);
int b = this.singleNumberXor(nums);
System.out.println("异或破解方案 = " + b);
int c = this.singleNumberHashSet(nums);
System.out.println("HashSet方案 = " + c);
}
(二)暴力破解方案
/**
* 暴力破解方案
*
* @param nums
* @return
*/
private int singleNumberViolence(int[] nums)
{
int a;
int result = 0;
for (int i = 0; i < nums.length; i++)
{
a = nums[i];
int index = 0;
for (int j = 0; j < nums.length; j++)
{
if (i != j && a == nums[j])
{
index++;
}
}
if (index == 0)
{
result = a;
}
}
return result;
}
(三)异或破解方案
/**
* 异或破解方案
*
* @param nums
* @return
*/
private int singleNumberXor(int[] nums)
{
int result = nums[0];
for (int i = 1; i < nums.length; i++)
result ^= nums[i];
return result;
}
(四)HashSet方案
/**
* HashSet方案
*
* @param nums
* @return
*/
private int singleNumberHashSet(int[] nums)
{
HashSet<Integer> a = new HashSet<>();
for (int num : nums)
if (!a.add(num))
a.remove(num);
return a.iterator().next();
}
(五)结果图
作者:王子威
四、总结
- 学习了只出现一次的数字
- 只写出了暴力破解,异或完全没想到…
- 因为异或的特性,重复的值会在下次出现时删掉对方,这个特性很有用,但注意这里适用于int或Integer类型
- HashSet的应用学习
- 算法兴趣+1 总:31
- 加强了对算法的分析能力