题解 | #数组中只出现一次的两个数字#

数组中只出现一次的两个数字

http://www.nowcoder.com/practice/389fc1c3d3be4479a154f63f495abff8

题意思路:
一个整型数组里除了两个数字只出现一次,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。

方法一:hash

将数组中所有元素遍历并映射到hash中统计数量,可以使用map保存数字和出现次数。

如果出现次数超过一次则删除数字

最后统计数组中只出现一次的两个数字。

复杂度分析

时间复杂度:O(NlogN),N数组的长度,遍历数组,map插入删除时间复杂度为logN;

空间复杂度:O(N),数组存储与读取数据。

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param array int整型vector 
     * @return int整型vector
     */
    vector<int> FindNumsAppearOnce(vector<int>& array) {
        // write code here
        map<int, int>mp;//使用map映射保存数字和出现次数
        vector<int> res;
        for(int i:array){//遍历数组
            if(mp[i])mp.erase(i);//如果出现次数超过一次则删除数字
            else mp[i]++;
        }
        for(auto i:mp)res.push_back(i.first);//最后统计数组中只出现一次的两个数字
        return res;
    }
};

方法二:位运算 异或

按位异或的4个特点:
(0) 只有在两个比较的位不同时其结果是1,否则结果为0

  (1) 0^0=0,0^1=1 0异或任何数=任何数

  (2) 1^0=1,1^1=0 1异或任何数=任何数取反

  (3) 任何数异或自己=把自己置0

题意表示除了出现一次的两个数字,其它数字都出现了两次

根据特点三可以使相同数字异或为0

然后0再异或出现一次的数字得到这个出现一次的数

但是异或所有数组元素后最后得到的异或结果是这两个只出现一次的异或结果

为了分别得到这两个数字,再次利用异或的性质0

从异或结果里面找一位1,因为某一位上异或结果是1的话,说明要找两个数,一个数这位是1,另一个是0。这一位是1的分成一组,这一位是0的分成一组,最后进行组内异或,这样得到两个数就是原来的数字

图解:

图片说明

复杂度分析

时间复杂度:O(N),N数组的长度,遍历数组,异或的时间复杂度为O(1);

空间复杂度:O(1),res数组只存了两个数

代码:

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param array int整型vector 
     * @return int整型vector
     */
    vector<int> FindNumsAppearOnce(vector<int>& array) {
        // write code here
        vector<int>res;
        int xorSum=0,a=0,b=0;
        for(int i:array){//遍历数组元素得到两个数的异或结果
            xorSum^=i;
        }
        int t=1;
        while((xorSum&t)==0){//找到异或结果中二进制位为1的数字
            t=t<<1;
        }
        for(int i:array){
            if(t&i){//根据异或性质 相同为0,不同为1 分别反推出两个数的结果
                a^=i;
            }
            else b^=i;
        }
        res.push_back(min(a, b));
        res.push_back(max(a,b));
        return res;
    }

};
全部评论

相关推荐

24分钟1.自我介绍2.黑盒测试用例设计方法3.运用刚才的测试方法对手机端淘宝购物车结算页面进行测试4.测试流程5.需求文档没有标明边界值,怎么确定边界值,确定边界值后怎么测6.你们公司自动化测试是测业务主流程还是新需求反问:不足之处答:问答问题前思考3s再答,针对提问再答
一笑而过2222:边:边界值分析法(处理输入边界) 类:等价类划分法(划分有效 / 无效输入) 定:判定表法(多条件组合的逻辑判定) 因:因果图法(分析输入输出的因果关系) 迁:状态迁移法(覆盖系统状态转换路径) 场:场景法(模拟端到端业务流程) 正:正交试验法(多因素组合的测试优化) 错:错误推测法(基于经验推测潜在漏洞) 记忆逻辑链(按测试场景优先级排序) 先处理明确输入:边界值 + 等价类(边类) 再处理条件组合:判定表 + 因果图(定因) 接着处理状态与流程:状态迁移 + 场景法(迁场) 最后优化多因素与补漏:正交试验 + 错误推测(正错)
查看6道真题和解析
点赞 评论 收藏
分享
06-11 13:34
门头沟学院 C++
offe从四面八方来:我真的没时间陪你闹了
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务