【LeetCode78】【位运算/递归】每日一题day21

32 篇文章 0 订阅
14 篇文章 0 订阅

这个是在补之前的题。这道题就是让你输出一个无重复数字的序列的全部子集,听起来hin简单,但是我却想不出来怎么做。看了题解之后两种方法都很简单,但是我自己又不会写。

方法一:每一个数字有取和不取两种状态,想到了什么?二进制。于是每次+1就可以枚举出所有情况

class Solution {
public:
    vector<int> t;
    vector<vector<int>> ans;

    vector<vector<int>> subsets(vector<int>& nums) {
        int n = nums.size();
        for (int mask = 0; mask < (1 << n); ++mask) {
            t.clear();
            for (int i = 0; i < n; ++i) {
                if (mask & (1 << i)) {
                    t.push_back(nums[i]);
                }
            }
            ans.push_back(t);
        }
        return ans;
    }
};

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/subsets/solution/zi-ji-by-leetcode-solution/

这是LeetCode官方题解上的代码,用到了位运算【呜呜呜呜我一点都不会,都是以前有能用位运算的解法偷懒没好好学】
x << n表示将x化为二进制表示,然后左移n位,也就是在右边添上n个零,也就相当于x乘2的n次方。第一层循环的意思大家应该能意会吧。
第二层循环这个实现非常妙。我们现在需要做的是看看哪一位是1,然后把对应位置的数字放到t里。这里用了一个mask & (1 << i),i是从1到nums.size()的。我们就能看出来1<<i就是依次把每一位放上1(比如001、010、100),然后再与我们枚举的mask做&操作,看看mask有哪些位是1
位运算真的太妙了呜呜呜呜我一定要好好学

我之前想用bitset来完成十进制到二进制的转换,然后再套个循环看看哪一位是1就行了,但是bitset和数组一样,大小得是个常数,所以这道题应该是就不好用了。

方法二:递归

class Solution {
public:
    void solve(vector<vector<int>> &ans, int cnt, vector<int> res, vector<int> nums)
    {
        if (cnt == nums.size()) 
        {
            ans.push_back(res);
            return;
        }
        res.push_back(nums[cnt]);
        solve(ans, cnt + 1, res, nums);
        res.pop_back();
        solve(ans, cnt + 1, res, nums);
    }
    vector<vector<int>> subsets(vector<int>& nums) {
        vector<vector<int>> ans;
        vector<int> res;
        solve(ans, 0, res, nums);
        return ans;
    }
};

完了我怎么看每道题都大有文章_(:з」∠)_这说明我啥也不会啊
我一开始写不出来的原因是我想,枚举第一位,选,ans.push_back(res),不选,ans.push_back(res),第二位,……这样的话就会出现0、00、000、1、10、100……
实际上还是要等整个序列枚举完了,到头了才能放进ans
【我怎么有这么多奇奇怪怪的错误啊呜呜呜呜】

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值