Leetcode:Single Number

戳我进传送门

 

Given an array of integers, every element appears twice except for one. Find that single one.



Note:

Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

 

这个题是让我大开眼界啊,一开始我左思右想,实在是无法在线性时间内搞定。

后来看了下题解,一下子惊呆了,原来还有这招。

对,就是异或这个武器。

对于异或,有以下性质:

0 ^ x = x



x ^ x = 0

 

在扩展一下:只要是偶数个x异或,结果就归零了。 这个性质很重要。

在这个题中,我们只要把全部数异或起来,那些出现偶数次的数全部归零,唯一一个出现奇数次的数就是最终的结果

class Solution {

public:

    int singleNumber(int A[], int n) {

        assert(A != NULL && n >= 0);

        int x = 0;

        for (int i = 0; i < n; ++i) {

            x ^= A[i];

        }

        return x;

    }

};

 

扩展:

1.除了唯一一个数出现奇数次,其余都出现偶数次,那么这个题解代码完全不需要改动

2.如果一个大小为n的数组(假设原本应该存放着1-n这n个数) 而实际上存放元素的取值范围是 1-(n+1) 也就是说有一个元素被丢弃了,现在要找出这元素。

这个题目很经典。首先如果数组是有序的,那么这个题目是一个很好的二分查找的拓展题

如果数组是无序的,那么这时就可以用到异或了。

假设丢失元素是x,那么1到n+1中除了x,其余所有元素都出现1次,我们可以虚拟一个1到n+1的数组,把这个数组和题中数组全部异或以来,

那么1到n+1中除了x以外,其余所有元素都出现了2次,只有x仅出现1次,最后的异或结果就是所求x

 

Single Number II:

Given an array of integers, every element appears three times except for one. Find that single one.



Note:

Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

 

解题分析:

同样考察位运算,有些复杂,我是直接采用空间换时间的方法,用一个哈希表,非常直观

class Solution {

public:

    int singleNumber(int A[], int n) {

        assert(A != nullptr && n >= 0);

        unordered_map<long, long> hash;

        for (int i = 0; i < n; ++i) {

            auto iter = hash.find(A[i]);

            if (iter == hash.end()) {

                hash.insert({A[i], 1});

            } else {

                hash[A[i]]++;

            }

        }

        for (auto pairVal : hash) {

            if (pairVal.second != 3) {

                return pairVal.first;

                break;

            }

        }

        

    }

};

 

 

你可能感兴趣的:(LeetCode)