开始时没看到空间复杂度的要求,选择使用键值对来存储数组信息。
第一次遍历数组,将数组中的数字及其出现次数记录到map中。
第二次遍历map,找到其中仅出现过1次的数,加入到结果数组中返回。

这种做法提交后运行时间打败前100%还让我有点小激动。

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param array int整型vector 
     * @return int整型vector
     */
    vector<int> FindNumsAppearOnce(vector<int>& array) {
        // write code here
        map<int, int> valueMap;
        vector<int> result;
        for(int i = 0;i < array.size();i++){
            if(valueMap.find(array.at(i)) == valueMap.end()){
                valueMap.insert(pair<int,int>(array.at(i),1));
            }
            else{
                valueMap[array.at(i)]++;
            }
        }
        map<int, int>::iterator iter = valueMap.begin();
        while(iter != valueMap.end()){
            if(iter->second == 1){
                result.push_back(iter->first);
                if(result.size() > 1){
                    return result;
                }
            }
            iter++;
        }
        return result;
    }
};



上面的做法中使用了一个map,所以空间复杂度为O(n),未满足题目要求。下面考虑空间复杂度为O(1)的做法。
首先需要知道的是,两个相同的数异或为0,即a^a=0,而异或运算满***换律,即a^b^a=a^a^b。
可以看出,在一条很长的连续异或运算中,偶数次重复的数对结果没有影响,最终产生影响的是奇数次重复数。在本体中,将所有数异或后,得到的是仅出现一次的那两个数的异或。
而异或的结果中为1的位数就是这两个数不同的位数,所以可以通过异或结果中其中的一个1来区分这两个数。最终将整个数组分成两部分异或,得到两个数即为结果。
这样做时间复杂度O(n),空间复杂度O(1),满足题目要求。但是值得注意的是跟上面的做法比起来运行时间还是慢了不少。

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param array int整型vector 
     * @return int整型vector
     */
    vector<int> FindNumsAppearOnce(vector<int>& array) {
        // write code here
        int num = 0;
        for(int i = 0;i < array.size();i++){
            num ^= array.at(i);
        }
        int com = 1;
        while((num & com) == 0){
            com <<= 1;
        }
        int num1 = 0;
        int num2 = 0;
        for(int i = 0;i < array.size();i++){
            if(array.at(i) & com){
                num1 ^= array.at(i);
            }
            else{
                num2 ^= array.at(i);
            }
        }
        return num1 > num2 ? vector<int>{num2, num1} : vector<int>{num1, num2};
    }
};