LeetCode136. 只出现一次的数字--数组--简单

题目描述:

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

说明:

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

示例 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)

发布了136 篇原创文章 · 获赞 112 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/heda3/article/details/104072582