136 Single Number

题目地址:https://leetcode.com/problems/single-number/

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

题目意思就是给一个数组,有一个数字只出现了一次,另外的数都出现了2次,要把这个出现一次的数找出来。

题目不是很难,一开始想用STL里面的map,遍历数组,把数组里面的数当成关键字,输入map,如果map里面没有这个索引,则加上这个索引,如果有,则删除这个索引。当数组遍历完成后,整个map就只有一个数,那个数就是只出现了一次的数字。


代码如下:

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        map<int,int> numCount;
        auto it=nums.begin();
        while(it!=nums.end())
        {
            ++numCount[*it];
            if(numCount[*it]==2)
                numCount.erase(*it);
            it++;
        }
       auto mit=numCount.begin();
        int singleNumber = (*mit).first;
        return singleNumber;
        
    }
}


这种方法在时间复杂度上,应该已经是最优的了,做到了O(N),但是空间复杂度在最坏的情况下也是O(N)。

后来发现一种更好的方法,在时间复杂度上是O(N),空间复杂度只有O(1),使用位操作的异或。两个数异或,如果一样,就是0,而0和其他数异或,那个数不会变,所以只要遍历所有数,循环进行异或操作,因为其他数都有两个,所以都会变成0,而那个单独的数和0异或,不会改变。遍历完所有的数之后,异或的结果就是那个独立的数。

代码:

class Solution {
public:
    int singleNumber(vector<int>& nums) {
       int result=0;
       auto it=nums.begin();
       while(it!=nums.end())
       {
           result ^=*it;
           it++;
       }
       return result;
    }
};

有时候,位操作还是比较神奇的,这方面比较不好想到,但是想到之后,对有些问题的解决,效率就会非常的高。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值