刷题记录2

第一题 力扣

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。 

 

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        unordered_map<int, int> hashtable;
        for (int i = 0; i < nums.size();i++) {
            auto it = hashtable.find(nums[i]);
            if (it != hashtable.end()) {
                hashtable.erase(it);
            }
            else{
                hashtable[nums[i]] = i;
            }
        }
        return hashtable.begin()->first;
    }    
};

第一时间想到的就是用hashtable,用stl的内置函数解决。

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

也可以遍历一次,使用位运算中的异或操作的性质找出只出现一次的数。

第二题 力扣

给你一个整数数组 nums 。数组中唯一元素是那些只出现 恰好一次 的元素。

请你返回 nums 中唯一元素的  。

class Solution {
public:
    int sumOfUnique(vector<int>& nums) {
        int hash[101];
        int sum=0;
        memset(hash,0,sizeof(hash));
        for(int i=0;i<nums.size();++i){
            ++hash[nums[i]];
        }
        for(int i=0;i<nums.size();++i){
            if(hash[nums[i]]==1){
                sum+=nums[i];
            }
        }
        return sum;
    }
};

与第一题类似,用hash表示每个数字的出现次数,最后简单加和即可。

class Solution {
public:
    int sumOfUnique(vector<int>& nums) {
        int ans =0;
        unordered_map<int,int>state;
        for(int num:nums){
            if(state[num]==0){
                ans+=num;
                state[num]=1;
            }
            else if(state[num]==1){
                ans-=num;
                state[num]=2;
            }
        }
        return ans;
    }
};

        题解里面的方法比较有意思,类似于一种状态机的方法,第一次遍历先全部加进去再设置状态, 如果遍历到已经有了的再减掉。

第三题 力扣

给定一个包含 [0, n] 中 n 个数的数组 nums ,找出 [0, n] 这个范围内没有出现在数组中的那个数。

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int n=nums.size();
        int sum= (0+n)*(1+n)/2;
        for(int i=0;i<n;++i){
            sum-=nums[i];
        }
        return sum;
    }
};

 总数里减去出现的就是未出现的数。

第四题 力扣

一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int n = nums.size();
        int sum = (n+1)*n/2;
        for(int i=0;i<nums.size();++i){
            sum-=nums[i];
        }
    return sum;
    }
};

与上面一题思路基本一致。

 第五题  力扣

给你两个整数,n 和 start 。

数组 nums 定义为:nums[i] = start + 2*i(下标从 0 开始)且 n == nums.length 。

请返回 nums 中所有元素按位异或(XOR)后得到的结果。

class Solution {
public:
    int xorOperation(int n, int start) {
        int ans =0;
        for(int i=0;i<n;++i){
            ans^=start + 2*i;
        }
        return ans;
    }
};

简单遍历数组元素即可。

第六题 力扣

每个非负整数 N 都有其二进制表示。例如, 5 可以被表示为二进制 "101",11 可以用二进制 "1011" 表示,依此类推。注意,除 N = 0 外,任何二进制表示中都不含前导零。

二进制的反码表示是将每个 1 改为 0 且每个 0 变为 1。例如,二进制数 "101" 的二进制反码为 "010"。

给你一个十进制数 N,请你返回其二进制表示的反码所对应的十进制整数。

class Solution {
public:
    int bitwiseComplement(int n) {
        int k =0;
        if(n==0){
            return 1;
        }
        while(1){
            if((1<<k)>n){
                break;
            }
            ++k;
        }
        return (1<<k)-1-n;
    }
};

 一个数10101与其反码01010之和为2^k-1,k为二进制的位数。

所以我们先用一个循环找出这个数二进制的位数,再算出2^k-1(即(1<<k)-1),减去n即可。

第七题  力扣

对整数的二进制表示取反(0 变 1 ,1 变 0)后,再转换为十进制表示,可以得到这个整数的补数。

例如,整数 5 的二进制表示是 "101" ,取反后得到 "010" ,再转回十进制表示得到补数 2 。
给你一个整数 num ,输出它的补数。

class Solution {
public:
    int findComplement(int num) {
            int k= 0;
            if(num==0){
                return 1;
            }
            while(1){
                if(((long long)1<<k)>num){
                    break;
                }
                ++k;
            }
            return ((long long)1<<k)-1-num;
    }
};

与上一题基本相同,但是<<过程中可能会溢出,所以强制转换成long long格式即可。

第八题 力扣 力扣

编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 '1' 的个数(也被称为 汉明重量).)

class Solution {
public:
    int hammingWeight(uint32_t n) {
        int sum=0;
        while(n){
            if(1&n){
                ++sum;
            }
            n>>=1;
        }
        return sum;
    }
};

 循环,利用1&n比较最后一位是否为1;

然后右移比较下一位,以此类推。

第九题 力扣

两个整数之间的 汉明距离 指的是这两个数字对应二进制位不同的位置的数目。

class Solution {
public:
    int hammingDistance(int x, int y) {
        int s=x^y;
        int sum=0;
        while(s){
            if(1&s){
                ++sum;
            }
            s>>=1;
        }
        return sum;
    }
};

不同的位数我们可以先用异或操作标识出来,再用循环以及同或操作数出不同的位数。

第十题 力扣

一次 位翻转 定义为将数字 x 二进制中的一个位进行 翻转 操作,即将 0 变成 1 ,或者将 1 变成 0 。

比方说,x = 7 ,二进制表示为 111 ,我们可以选择任意一个位(包含没有显示的前导 0 )并进行翻转。比方说我们可以翻转最右边一位得到 110 ,或者翻转右边起第二位得到 101 ,或者翻转右边起第五位(这一位是前导 0 )得到 10111 等等。
给你两个整数 start 和 goal ,请你返回将 start 转变成 goal 的 最少位翻转 次数。

class Solution {
public:
    int minBitFlips(int start, int goal) {
        int s =start^goal;
        int sum=0;
        while(s){
            if(1&s){
                ++sum;
            }
            s>>=1;
        }
        return sum;
    }
};

这个题目中所说的最小位翻转次数就是两个数之间的“汉明距离”。 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值