DFS暴力+剪枝

DFS+剪枝

  • DFS:深度优先搜索,可通过回溯筛选符合条件的子集;
  • 剪枝:特定环境下,减去多余的枝节,减少递归次数,减小时间复杂度;

题目:统计按位或能得到最大值的子集数目

  • 给你一个整数数组 nums ,请你找出 nums 子集 按位或 可能得到的 最大值 ,并返回按位或能得到最大值的 不同非空子集的数目 。

如果数组 a 可以由数组 b 删除一些元素(或不删除)得到,则认为数组 a 是数组 b 的一个 子集 。如果选中的元素下标位置不一样,则认为两个子集 不同 。

对数组 a 执行 按位或 ,结果等于 a[0] OR a[1] OR … OR a[a.length - 1](下标从 0 开始)。
示例 1:

输入:nums = [3,1]
输出:2
解释:子集按位或能得到的最大值是 3 。有 2 个子集按位或可以得到 3 :

  • [3]
  • [3,1]
    示例 2:

输入:nums = [2,2,2]
输出:7
解释:[2,2,2] 的所有非空子集的按位或都可以得到 2 。总共有 23 - 1 = 7 个子集。
示例 3:

输入:nums = [3,2,1,5]
输出:6
解释:子集按位或可能的最大值是 7 。有 6 个子集按位或可以得到 7 :

  • [3,5]
  • [3,1,5]
  • [3,2,5]
  • [3,2,1,5]
  • [2,5]
  • [2,1,5]

1>读懂题

  • 1.找出原数组中按位或最大值;

  • 2.找出其中符合按位或等于数组最大值的子数组;
    注意:其中子集是根据索引,不是根据元素值
    即[2,2,2]中[null,2,2]和[2,null,2]都是[2,2],但被认为是两个子集

  • tips:按位或: a[0] OR a[1] OR … OR a[a.length - 1](下标从 0 开始)。

2>求按位或最大值

  • 求按位或的值时,max的值只会变大,不可能变小,所以直接遍历数组求解即可;

3>剪枝

  • 剪枝即减去多余枝节:
    已知:求解按位或的值时之会变大不会变小;
    且步骤二中已求解数组的按位或最大值
    所以:当遍历到二叉树的某个节点满足按位或等于最大值 时,该节点的所以子节点都符合条件,ans+2^n;
    结论:当遍历到满足条件的节点时,它的子节点不许再遍历,进行剪枝

4>DFS

  • 进行深度搜索时,无非两种情况:
  • 1.选择该索引指向的元素;
  • 2.不选择该索引指向的元素

题解

class Solution {
    public int ans = 0;
    public int countMaxOrSubsets(int[] nums) {
        int sum = 0;
        for(int i : nums){
            sum |= i;
        }
        dfs(nums,sum,0,0);
        return ans;
    }
    private void dfs(int[] nums,int sum,int idx,int tmp){
        if(tmp == sum){
            ans += 1<<(nums.length-idx);
            return;
        }
        //判断,是否超出数组长度,进行回溯
        if(nums.length == idx){
            return;
        }

        dfs(nums,sum,idx+1,nums[idx]|tmp);
        dfs(nums,sum,idx+1,tmp);
    }
}

结论

  • 剪枝+DFS+按位或 yyds

声明

  • 原作者:E.L.E

  • <本文章著作权归作者所有,商业转载请获得作者授权,非商业转载请注明出处>

  • <欢迎大家评论>

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值