题目描述:
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,1]
输出: 1
示例 2:
输入: [4,1,2,1,2]
输出: 4
参考:https://leetcode-cn.com/problems/single-number
解题思路:
1、快速排序
1)数组快速排序
2)排序后的相同两个元素都是比较靠近的,两两比较找到以后赋予特殊的值
3)逐一查找不是特殊值的数字就可以找到
//C++ 快排
class Solution
{
public:
int singleNumber(vector<int>& nums)
{
int len = nums.size();
sort(nums.begin(), nums.end());//快排
for (int i=0; i<len-1; i++)
{
if (nums[i]!=-1 && nums[i]==nums[i+1])
{
nums[i] = -1;
nums[i+1] = -1;
}
}
for (int i=0; i<len; i++)
{
if (nums[i] != -1)
return nums[i];
}
return -1;
}
};
算法复杂度分析:
时间复杂度:O(nlogn),快速排序的nlogn+两次循环的2n
空间复杂度:O(n) , 快速排序的递归过程需要的内存空间
2、使用哈希表
键为各元素,值为出现的次数
//python哈希表
1)找到相应的键值则移除(说明该数存在了两次),否则找不到则在该键上赋值次数1(说明只有该数只出现一次)
2)最后hash_table里只存在一个元素的数,返回并移除
#python
class Solution(object):
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
hash_table = {}
for i in nums:
try:
hash_table.pop(i)
except:
hash_table[i] = 1
return hash_table.popitem()[0]
函数调用说明:
dictionary.pop(key[, default]) 找到key并移除
https://www.geeksforgeeks.org/try-except-python/
https://www.programiz.com/python-programming/methods/dictionary/pop
https://www.programiz.com/python-programming/methods/dictionary/popitem
//Java 哈希表
class Solution {
public int singleNumber(int[] nums)
{
Map<Integer, Integer> map = new HashMap<>();//创建哈希表
for (Integer i : nums) {
Integer count = map.get(i);//判断i是否在map里,若不在则返回null 否则返回对应的键值
count = count == null ? 1 : ++count;//相应的元素对应的值count
map.put(i, count);//往哈希表里添加键值对
}
for (Integer i : map.keySet()) //map.keySet()返回键值的一个集合,也即是该集合内不包含重复元素
{
Integer count = map.get(i);
if (count == 1)
{
return i;
}
}
return -1; // can't find it.
}
}
算法复杂度分析:
时间:O(n)
空间:O(n)
函数调用参数说明:
https://www.geeksforgeeks.org/map-get-method-in-java-with-examples/
3、集合运算相减
集合运算,差集
例如:给的数组为a+b+b+c+c
运算方式;2*(a+b+c)-(a+b+b+c+c)=a
//c++
class Solution {
public:
int singleNumber(vector<int>& nums) {
int len = nums.size();
set<int> s;//创建集合,不包含重复的元素
int sum1 = 0;
int sum2 = 0;
for (int i=0; i<len; i++)
{
sum1 += nums[i];//1所有元素相加
if (s.count(nums[i]) == 0)//获取所有不重复的元素和
{
s.insert(nums[i]);
sum2 += nums[i];
}
}
return 2*sum2 - sum1;//差集
}
};
算法复杂度分析
时间复杂度:O(n)
空间复杂度:O(n)
4、异或(位运算)
1)0^a=a; a^a=0;a^a^b=b
#python异或运算
class Solution(object):
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
a = 0
for i in nums:
a ^= i
return a
//C++异或运算
class Solution {
public:
int singleNumber(vector<int>& nums)
{
int len = nums.size();
int res = 0;
for (int i=0; i<len; i++)
res ^= nums[i];
return res;
}
};
//Java 异或运算
class Solution {
public int singleNumber(int[] nums)
{
int ans = nums[0];
if (nums.length > 1)
{
for (int i = 1; i < nums.length; i++)
{
ans = ans ^ nums[i];
}
}
return ans;
}
}
算法复杂度分析:
时间:O(n)
空间:O(1)