LeetCode初级算法——其他——算法总结

LeetCode初级算法——其他——算法总结

PS:算法并非原创,总结的本意在于温故知新、巩固知识。侵删。

1、位1的个数
使用C++解答,代码如下:

#include 
using namespace std;
class Solution {
public:
	//方法1:O(32)
	int hammingWeight1(uint32_t n) {
		int result = 0;
		for (int8_t i = 0; i < 32; i++)
		{
			if (n & (1 << i)) {
				++result;
			}
		}
		return result;
	}
	//方法2:O(m),m为n的二进制的位数
	//减1操作将最右边的符号从0变到1,从1变到0,与操作将会移除最右端的1。如果最初n有X个1,那么经过X次这样的迭代运算,n将减到0。
	int hammingWeight2(uint32_t n) {
		int count = 0;
		while (n != 0) {
			n = n & (n - 1);
			count++;
		}
		return count;
	}

	// 方法3:汉明重量,O(1)
	//https://blog.csdn.net/sword52888/article/details/86513023 超详细解释
	//但要注意溢出问题,有可能报错,需要将溢出的进行处理!!!
	//0x55555555 == = >> 0101 0101 0101 0101 0101 0101 0101 0101,每两位为一组
	//0x33333333 == = >> 0011 0011 0011 0011 0011 0011 0011 0011,每四位为一组
	//0x0F0F0F0F == = >> 0000 1111 0000 1111 0000 1111 0000 1111,每八位为一组
	//0x01010101 == = >> 0000 0001 0000 0001 0000 0001 0000 0001,将4组8位累加,刚好是32位的前8位,后面24位可以舍去,前面溢出的更可以舍去
	int hammingWeight(int32_t i)
	{
		i = (i & 0x55555555) + ((i >> 1) & 0x55555555);
		i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
		i = (i & 0x0F0F0F0F) + ((i >> 4) & 0x0F0F0F0F);
		i = (i * (0x01010101) >> 24);
		return i;
	}
};

算法解析:
算法一:n & (1 << i)表示进行对应位的与运算,详情可见此链接,如果当前位是1的话则亦或运算结果为非0,如果不是的话则结果为0,只需要一直对1左移并判断,循环32次即可。
算法二:减1操作将最右边的符号从0变到1,从1变到0,这个可以理解。而与操作将会移除最右端的1(可自行演算)。如果最初n有X个1,那么经过X次这样的迭代运算,n将减到0。
算法三:汉明重量 (variable-precision SWAR 算法),第一次与0x55555555的运算将数据分成2位1组,得到的结果表示每组的1的数量。原因是i&0x55555555得到的是每组偶数位的1的数量,(i>>1)&0x55555555得到的是每组奇数位的1的数量,最后两两相加,得到每组的1的数量。
之后与0x33333333的操作,将上一操作的结果进行4位1组,得到的结果需要将组内的值进行相加,得到每4位的1的个数结果。上一轮操作,得到2位1组的1的个数,此处将每两组的1的个数相加。具体操作是通过0x0011进行取值,取出前2位和后2位的结果进行相加。每四位都进行这样的操作。
之后再和0x0f0f0f0f进行操作,得到8位1组的1的个数,思想和上述类似,不赘述。
最后一步,得到算法的结果,乘法的乘数为0x01010101,根据通过摆出乘法的竖式得出最后结果,只有在最高位的0x01才能进行每个低四位的相加操作。

点击查看参考博客

算法占用时空间资源:
LeetCode初级算法——其他——算法总结_第1张图片

2、汉明距离
使用C++解答,代码如下:

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

算法解析:
按位分别取出两个数对应位上的数并异或(如何取位可参考上一题的算法一)我们知道异或的性质上相同的为0,不同的为1,我们只要把为1的情况累加起来就是汉明距离了。

点击查看参考博客

算法占用时空间资源:
LeetCode初级算法——其他——算法总结_第2张图片

3、颠倒二进制位
使用C++解答,代码如下:

class Solution {
public:
    uint32_t reverseBits(uint32_t n) {
        int A[32];
        for(int i=0;i<32;i++){
            if(n>=1){
                A[i]=n%2;
                n=n/2;
            }
            else{
                A[i]=0;
            }
                
        }
        uint32_t number=0;
        for(int i=0;i<32;i++){
            number += A[i]*pow(2,31-i);
        }
        return number;
    }
};

算法解析:
采用长度为32的数组A存储颠倒结果,然后在通过进值转换运算得出number的结果。在颠倒的过程中,采用的是二进制转换的思想。十进制转为二进制的转换过程中,我们通过对应数据进行除二操作,得到的余数颠倒得到一个十进制数的二进制表示。那么现在即可直接进行除二操作,存储余数,得到的即是颠倒的二进制结果。

点击查看参考博客

算法占用时空间资源:
LeetCode初级算法——其他——算法总结_第3张图片

4、杨辉三角
使用C++解答,代码如下:

 
class Solution {
public:
    vector<vector<int>> generate(int numRows) 
    {
        vector<vector<int>> nums1;
        for(int i=1;i<=numRows;i++)           //对于第i行,存i个元素,先赋值为0,后期存入其他值覆盖
            nums1.push_back(vector<int>(i,0));
        
        for(int i=0;i<numRows;i++)             //遍历每个位置存值
        {
            for(int j=0;j<=i;j++)
            {
                if(j==0 || j==i)
                {
                    nums1[i][j]=1;    //边界赋值为1   
                }
                else
                {
                    nums1[i][j]=nums1[i-1][j-1]+nums1[i-1][j];
                }
            }
        }
        return nums1;
    }
};

算法解析:
定义一个int型的二维数组nums1存储结果,然后进行初始化,同时确定数组的形状(塔形),之后遍历指定数量的行,边缘赋值为1,内部元素通过杨辉三角的运算规律进行计算,每一层都依赖于上一层的元素结果。

点击查看参考博客

算法占用时空间资源:
LeetCode初级算法——其他——算法总结_第4张图片

5、有效的括号
使用JAVA解答,代码如下:

class Solution {
    public boolean isValid(String s) {
        if(s==null || "".equals(s)) {
            return true;
        }
        //用栈保存 (,[,{
        Stack<Character> stack = new Stack<Character>();
        //map中保存的是 ):(, ]:[,}:{
        //当遍历到 )时候就会去map中找对应的value,也就是(
        //再用这个value和stack弹出的元素比较,如果相等则匹配上,不等则返回false
        //这里也可以用数组来存,为了简单就用map表示了
        HashMap<Character,Character> map = new HashMap<Character,Character>();
        map.put(')','(');
        map.put(']','[');
        map.put('}','{');
        for(int i=0;i<s.length();i++) {
            char c = s.charAt(i);
            //如果map中不包含 (,[,{,就将这个字符放入栈中
            if(!map.containsKey(c)) {
                stack.add(c);
            } else {
                //如果遍历的字符不在map中,也就是说这个字符是),],},那么就要跟栈中的元素比较
                //首先要判断栈是否为空,如果输入的字符是 )() ,那么当遍历到第一个)时,栈为空
                if(stack.size()==0) {
                    return false;
                }
                //取出栈顶的元素
                Character tmp = stack.pop();
                //假设当前遍历到的元素是 ],那么从map中取到的value就是 [
                //如果栈顶的元素是 (,则不匹配返回false,否则继续
                if(map.get(c)!=tmp) {
                    return false;
                }
            }
        }
        //返回的时候还要判断栈是否为空
        //如果输入的字符串是 (((,那么最后栈就不为空
        return (stack.empty()? true : false);
    }
}

算法解析:
算法采用栈进行操作,当遍历到这三个字符的时候,就将其保存到栈中。遇到左括号则压入栈,遇到右括号则检查栈顶元素是否与该括号对应。如果对应,那么栈顶元素出栈,进行后续操作,如果不匹配,直接可知表达式无效。遍历到表达式末尾,如果栈内仍然元素,那么可知表达式无效。

点击查看参考博客

算法占用时空间资源:
LeetCode初级算法——其他——算法总结_第5张图片

6、缺失数字
使用C++解答,代码如下:

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

算法解析:
先通过sort函数将函数进行大小排序,然后进行遍历,如果下标和元素值不对应,那么即可确定缺失的数字。

点击查看参考博客

算法占用时空间资源:
LeetCode初级算法——其他——算法总结_第6张图片

你可能感兴趣的:(Leetcode,算法,leetcode,数据结构,c++,java)