LeetCode初级算法(其他篇)

缺失数字

最初的想法是将0到n全部加起来,再减去输入的数字之和,那么差如果非零的话就是我们所需要的数字。但是一想,可能会发生溢出错误,所以换了个思路,先进行排序后,后一个元素与该元素的差是否为1,不为1的话就说明缺了元素。这种方法不会发生溢出错误,代码如下:

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        if(nums[0]!=0) return 0;
        int l=nums.size();
        if(nums[l-1]!=l-1)
        {
            for(int i=1;i<nums.size();i++)
                if((nums[i]-nums[i-1])!=1) return nums[i-1]+1;
        }
        return l;
    }
};

位1的个数

用1进行循环位与比较就可以了,不为0的话就说明有1,累加器加1,代码如下:

class Solution {
public:
    int hammingWeight(uint32_t n) {
        int count=0;
        for(int i=0;i<32;i++)
        {
            count += (n&00000000000000000000000000000001);
            n=n>>1;
        }
        return count;
    }
};

颠倒二进制位

这道题比较简单,涉及到二进制的话就一定是位运算;所以可以new一个新的32位二进制数res,n每次右移、res每次左移,res在移动过程中实现位数的存储,代码如下:

class Solution {
public:
    uint32_t reverseBits(uint32_t n) {
        uint32_t res=0;
        for(int i=0;i<32;i++)
        {
            if(n&1==1)
                res=(res<<1)+1;
            else
                res=res<<1;
            
            n=n>>1;
        }
        return res;
    }
};

有效的括号

以前学习数据结构的时候一定介绍过利用栈的四则运算,栈的作用当时就是存储括号并优先计算括号内的表达式。这道题很类似,而且简单许多,只用判断括号就行了,直接见代码:

class Solution {
public:
    bool isValid(string s) {
        stack<char> res;
        for(int i=0;i<s.size();i++)
        {
            if(s[i]=='('||s[i]=='['||s[i]=='{') res.push(s[i]);
            else{
                if(res.empty()) return false;
                if(s[i]==')' && res.top()!='(') return false;
                if(s[i]==']' && res.top()!='[') return false;
                if(s[i]=='}' && res.top()!='{') return false;
                res.pop();
            }
        }
      if(res.empty())
           return true;
        else
           return false;
    }
};

汉明距离

这道题我是用x&(1<<i))^(y&(1<<i)进行判断的,即对x与y的二进制每一位进行判断,如果位为1的话x&(1<<i)就为1,再与y&(1<<i)进行异或运算,若相异就将计数器加1,表示该位不一致。

class Solution {
public:
    int hammingDistance(int x, int y) {
     int count=0;
        for(int i=0;i<32;i++)
        {
           if((x&(1<<i))^(y&(1<<i))) 
               count++;
        }
     return count;
    }
};

此外还有其他判断方式:

class Solution {
public:
    int hammingDistance(int x, int y) {
        int res = 0, exc = x ^ y;
        while (exc) {
            ++res;
            exc &= (exc - 1);
        }
        return res;
    }
};

这里是将x与y直接进行异或计算,存入exc中;接下来进入总循环数为1的个数的循环中,再用exc &= (exc - 1)快速的溢出最右边的位1;这个方法比较高效。

帕斯卡三角形

这个自己没有想出来,看来还是对vector这种结构不太熟悉,还需锻炼。先放上代码:

class Solution {
public:
    vector<vector<int>> generate(int numRows) {
        vector<vector<int> > res;
        if(numRows<=0) return res;
        res.assign(numRows,vector<int>(1));
        for(int i=0;i<numRows;i++)
        {
            res[i][0]=1;
            if(i==0) continue;
            for(int j=1;j<i;j++)
            {
                res[i].push_back(res[i-1][j]+res[i-1][j-1]);
            }
            res[i].push_back(1);
        }
        return res;
    }
};

大神的代码很清晰,帕斯卡三角形两边都是1,中间是通过上一层的数之和计算出来的。所以两边都是取为1的,中间是通过一个循环存储上一层两数之和的。

posted @ 2018-04-19 13:23  MrYun  阅读(167)  评论(0编辑  收藏  举报