题目:
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,1]
输出: 1
示例 2:
输入: [4,1,2,1,2]
输出: 4
一、个人分析思路:
熟读题目,如果可以使用额外空间,可以利用Set集合的元素不可重复这一特性解题。既然需要满足不使用额外空间,那就得另辟蹊径。
可以差不多理解,该数组非空,且数组长度为奇数。那么可以先对该数组进行排序,调用Arrays.sort()方法,然后,分三种情况讨论:
①若数组的第一个元素,和第二个元素不同,那第一个元素就是目标元素;
②若数组的最后一个元素,和倒数第二个元素不同,那最后一个元素就是目标元素;
③若数组的中间元素,既与前一个不同,又与后面不同,那它也是目标元素。
class Solution {
public int singleNumber(int[] nums) {
//只有一个元素,直接返回
if(nums.length==1) return nums[0];
//可以先排个序
Arrays.sort(nums);
//根据题目意思,数组长度是奇数
//第一个数与后者不一样,返回第一个
if(nums[0]!=nums[1]) return nums[0];
//最后一个数与前者不一样,返回最后一个
if(nums[nums.length-1]!=nums[nums.length-2]) return nums[nums.length-1];
//中间的数
for(int i=1;i<nums.length-1;i++){
if((nums[i]!=nums[i-1]) && (nums[i]!=nums[i+1]))
{
return nums[i];
}
}
//否则就不存在
return (Integer)null;
}
}
该方法:时间复杂度为O(nlogn),空间复杂度为O(1),执行的结果如下图所示:
该方法缺点在于,数组的相对位置发生了改变(虽然题目没有这项要求),且算法调用了一次排序方法的API,从而时间复杂度相对高了点,且有点取巧的味道。
二、主流的思路:
运用异或的方法,此方法很巧妙,算法的时间复杂度为O(n),代码非常简洁,且原有的数组相对位置没有改变。具体可见:力扣https://leetcode-cn.com/problems/single-number/solution/zhi-chu-xian-yi-ci-de-shu-zi-by-leetcode-solution/