美文网首页
2020-03-08 刷题5(位运算,动态规划)

2020-03-08 刷题5(位运算,动态规划)

作者: nowherespyfly | 来源:发表于2020-03-09 10:25 被阅读0次

191 位1的个数

标签:位运算
最简单的逐位统计法:

class Solution {
public:
    int hammingWeight(uint32_t n) {
        int cnt = 0;
        while(n > 0){
            cnt += n % 2;
            n = n >> 1;
        }
        return cnt;
    }
};

这种做法需要循环n的有效位数遍,即使在中间有0,也会占用一次循环。

一个更加tricky的做法,是利用n和n-1的性质,因为n最低位的1,对应到n-1一定是0,所以n&n-1 就可以把n最低位的1消去。重复数次,n就可以变成0.这种做法循环的次数等于n中1的位数,平均情况下,比第一种做法要好一些。


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

我发现我写代码越来越简洁了哈~~~~~


461 汉明距离

标签:位运算
这个题就是上一题的增强版,多了一步计算两个数异或的操作。

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

322 零钱兑换

这是个很典型的动态规划问题,当金额为n时,

dp(n) = min(dp(n - c_k)) + 1.
dp(0) = 0.

递推公式很好想,但是代码不好写,采用递归的做法,递归太深时占用栈空间过多,而且会有很多重复计算。所以采用迭代的写法,自底向上依次计算。

两层循环是肯定的,一层循环次数为金额,另一层为硬币种类,第一种做法是将金额设为外层循环,硬币种类为内层循环,内层循环停止条件受外层金额影响;第二种做法是将硬币种类为外层循环,金额为内层循环,内层循环起始条件受外层硬币面值影响。两种做法都可以保证唯一性。这里采用第二种做法。

class Solution {
public:
    int coinChange(vector<int>& coins, int amount){
        int *dp = new int[amount+1];
        for(int i = 1; i <= amount; i++)
            *(dp + i) = INT_MAX;
        *dp = 0;
        for(int i = 0; i < coins.size(); i++){
            for(int j = coins[i]; j < amount + 1; j++){
                if(*(dp + j - coins[i]) < *(dp + j) - 1){
                    *(dp + j) = *(dp + j - coins[i]) + 1;
                }
            }
        }
        if(*(dp + amount) != INT_MAX) return *(dp + amount);
        return -1;
    }
};

时间复杂度:O(MN), 空间复杂度:O(M)
M是总金额,N为硬币种类。


190 颠倒二进制位

标签:位运算
采用逐位左移的操作,最低位左移31位放到最高位,然后n整体右移一位后当前最低位左移30位,依次操作直到n变为0.

class Solution {
public:
    uint32_t reverseBits(uint32_t n) {
        int ans = 0;
        for(int i = 31; i >=0; i--){
            ans += (n & 1) << i;
            n = n >> 1;
            if(n == 0) break;
        }
        return ans;
    }
};

268 缺失的数字

标签:位运算
这个题目其实跟之前做过的重复数字是一样的道理,利用了自己异或自己为0。先从0到n异或一遍,然后把数组里的数字依次异或一遍,最后得到的就是只异或过一次,也就是缺失的那个数字。

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

相关文章

  • 2020-03-08 刷题5(位运算,动态规划)

    191 位1的个数 标签:位运算最简单的逐位统计法: 这种做法需要循环n的有效位数遍,即使在中间有0,也会占用一次...

  • 如何解决动态规划问题

    曾经的我以为动态规划很神秘,很难理解。后来随着刷的动态规划相关的题越来越多,对于动态规划也就驾轻就熟了。我一开始来...

  • LeetCode刷题之位运算

    1342. 将数字变成 0 的操作次数 给你一个非负整数 num ,请你返回将它变成 0 所需要的步数。 如果当前...

  • leetcode刷题之动态规划

    1,括号生成—— 0022 回溯法数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有...

  • LeetCode刷题笔记(九)位运算

    九. 位运算 位运算不需要转换成10进制, 因此处理速度非常快。实战常用位运算 x & 1 == 1 判断奇偶 (...

  • 前端算法

    标签: 算法 正文 1.位运算 2.两个数不使用四则运算得出和 3.排序 4.动态规划

  • [leetcode刷题笔记]数学与位运算

    位运算是二进制中比较常见的运算,包括按位与&,按位或|,非~,异或∧ 等,本文记录LeetCode刷题一些知识点,...

  • LeetCode 刷题集 - 动态规划(4)

    动态规划定义[https://en.wikipedia.org/wiki/Dynamic_programming]...

  • 动态规划刷题整理(持续更新)

    (持续更新) 奇怪的汉诺塔(4柱汉诺塔) 描述汉诺塔问题,条件如下:1、这里有A、B、C和D四座塔。2、这里有n个...

  • LeetCode刷题笔记(五)动态规划

    五. 动态规划 动态规划的两个核心要素:状态空间和状态方程。 53. 最大子序和 题目:给定一个整数数组 nums...

网友评论

      本文标题:2020-03-08 刷题5(位运算,动态规划)

      本文链接:https://www.haomeiwen.com/subject/luzddhtx.html