leetcode【136、137】Single Number、Single Number II【c++版,时间线性,无额外空间】

问题描述136:

Given a non-empty 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?

Example 1:

Input: [2,2,1]
Output: 1

Example 2:

Input: [4,1,2,1,2]
Output: 4

源码136:

最近leetcode貌似又出问题了,所以的方法效率都贼低,都是不到10%那样。等后面修复好了我在展示吧。

这题是剑指offer第56题剑指offer总纲的一个简易版。所有数字异或本身都是0,0与数字异或等于本身,所以我们吧所有的元素异或到一起,就解决了问题。Solution里面也太扯了,不是时间不是线性就用了额外空间,根本不满足题目要求。

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

问题描述137:

Given a non-empty array of integers, every element appears three times except for one, which appears exactly once. Find that single one.

Note:

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

Example 1:

Input: [2,2,3,2]
Output: 3

Example 2:

Input: [0,1,0,1,0,1,99]
Output: 99

源码137:

同样是剑指offer的第56问剑指offer总纲。因为用到的数组都是常熟大小的,内循环也是常数的,所以时间是线性的,空间是常数的。

思路就是统计int类型每一位的数字,然后%3,这样就能筛出需要的数字。

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int n=nums.size();
        int bitsum[32] = {0};
        for(int i=0; i<n; i++){
            long bitmask = 1;
            for(int j=31; j>=0; j--){
                int bit = nums[i] & bitmask;
                if(bit)     bitsum[j] += 1;
                // cout<<bitmask<<endl;
                bitmask = bitmask<<1;
            }
        }
        int result = 0;
        for(int i=0; i<32; i++){
            result = result<<1;
            result += bitsum[i] % 3;
        }
        return result;
    }
};

大佬的博客上有比较简洁的做法,思路还是一样的:

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int n = nums.size(), result = 0;
        for(int i=0; i<32; i++){
            int sum = 0;
            for(int j=0; j<n; j++){
                sum += (nums[j]>>i) & 1;
            }
            result += (sum % 3)<<i;
        }
        return result;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值