136. 只出现一次的数字

发布时间 2023-10-15 21:30:04作者: DawnTraveler

1.题目简介

2.题解

本题思路参考了某位大大的题解,链接:https://leetcode.cn/problems/single-number/solutions/5118/xue-suan-fa-jie-guo-xiang-dui-yu-guo-cheng-bu-na-y/

2.1 数组/哈希表解法

思路

这里很容易想法就是成对存储:数(键)和数出现的次数(键值),所以使用数组和哈希表存储都是比较容易想到的。
但是有一个关键问题(且该算法只使用常量额外空间),而这两种方法都要使用额外的空间,空间代价为o(n)

代码(这里只展示使用哈希表的解法,数组思路同理)

class Solution {
public:
    int singleNumber(std::vector<int>& nums) {
        std::unordered_map<int,int> map;
        for (int num:nums){
            map[num]++;
        }
        for (auto pair:map){
            if (pair.second == 1) return pair.first;
        }
        return 0;
    }
};

结果展示

这里是能过通过测试用例的,但是明显空间使用率过低

2.2暴力枚举

思路

如果想要减少空间使用,那就并不能使用数组/哈希表记录每个元素的出现次数,也就是一个时间点,我最多只能知道一个元素的出现次数
很容易想到的便是暴力枚举(两层for循环),外层循环从数组中挑出一个元素,内层循环将其与数组全员(除本身外)比较,若有相同即return

代码

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        for (int i = 0; i < nums.size(); i++){
            for(int j = 0; j < nums.size(); j++)
            {
                if (nums[i] == nums[j] && i != j) break;
                else if(j == nums.size() - 1) return nums[i];
            }
        }
        return false;
    }
};

结果展示

并没有通过,因为这里的时间代价是o(n^2),超出了时间限制

2.3 快排+寻找

思路

如何将时间代价从o(n^2)减少到o(n)是最大的问题,快排可以将时间代价减少到O(nlogn)
这里是可以在快排途中判断并且获取答案的,这里博主偷懒,直接使用了封装好的快排,在之后进行判断;
总体算两部分,快排O(nlogn),寻找o(n),结合一下时间代价还是O(nlogn)

代码

class Solution {
public:
    int singleNumber(std::vector<int>& nums) {
        int count = 0;
        std::sort(nums.begin(),nums.end());
        for (int i = 0; i < nums.size(); i++) {
            if (i == nums.size() - 1 && count == 0) return nums[i];
            if (nums[i] == nums[i+1]) count++;
            else if(count) count = 0;
            else return nums[i];
        }
        return false;
    }
};

结果展示

2.4 异或(最优解)

思路

这里主要利用异或归零律和交换律,恒等律

举个例子就懂了

代码

class Solution {
public:
    int singleNumber(std::vector<int>& nums) {
        int temp = nums[0];
        for (int i = 1; i < nums.size(); i++){
            temp = temp ^ nums[i];
        }
        return temp;
    }
};

结果展示