🌈【LeetCode 2044. 统计按位或能得到最大值的子集数目 】- JavaScript(DFS)

135 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第24天,点击查看活动详情


说明:文章部分内容及图片出自网络,如有侵权请与我本人联系(主页有公众号:小攻城狮学前端)

作者:小只前端攻城狮、 主页:小只前端攻城狮的主页、 来源:掘金

GitHub:P-J27、 CSDN:PJ想做前端攻城狮

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


【LeetCode 2044. 统计按位或能得到最大值的子集数目 】- JavaScript(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]

暴力DFS

思路分析:

暴力DFS的思路:

主要目的是计算最大值,最大值是所有位或的结果。直接写dfs深度优先搜索,将index当做是当前的序号,count变量为之前所有节点计算的结果(计算包括或或者是跳过),dfs的关键是跳过当前节点或者不跳过当前节点。这里需要注意一点就是是如果前一个节点是跳过的,count就算和max相等也不应该计入结果。具体实现步骤如下:

  • 首先用位运算对nums所有元素或得到一个最大值。
    • max |= num;
  • dfs所有情况, 可选或可不选.
    • dfs(0, nums, 0, max);

提示:中间过程中可以加上必要的剪枝:当前 按位或 值为最大值时,不需要继续 “深入”,因为 按位或 的操作只会增大值,不会减小值,这说明剩下未遍历的值不会改变原先 按位或 的值。

var maxProfitAssignment = function(difficulty, profit, worker) {
  const l = difficulty.length;
  const map = new Map();

  for (let i = 0; i < l; i++) {
    map.set(difficulty[i], Math.max(map.get(difficulty[i]) || 0, profit[i]));
  }
  const max = Math.max(...difficulty, ...worker);
  const dp = new Array(max + 1).fill(0);
  for (let i = 1; i <= max; i++) {
    dp[i] = Math.max(dp[i - 1], map.get(i) || 0);
  }
  return worker.reduce((sum, item) => sum + dp[item], 0);
};

思考

这题用上位运算之后,就方便很多了,直接爆破。位运算还是那么强势。👀🤞


感谢阅读,希望能对你有所帮助,文章若有错误或者侵权,可以在评论区留言或在我的主页添加公众号联系我。

写作不易,如果觉得不错,可以「点赞」+「评论」 谢谢支持❤