统计按位或能得到最大值的子集数目(三) 方法二回溯思路记 n 是数组 nums 的长度。方法一的缺点是计算不同状态的按位或的值都需要消耗 O(n) 的时间。这一步部分可以进行优化。每个长度为 n 比特的状态的按位或的值都是可以在长度为 n−1 比特的状态的按位或的值上计算出来的而这个计算只需要消耗常数时间。以此类推边界情况是长度为 0 比特的状态的按位或的值。我们定义一个搜索函数参数 pos 表示当前下标orVal 表示当前下标之前的某个子集按位或值这样就可以保存子集按位或的值的信息并根据当前元素选择与否更新 orVal 。当搜索到最后位置时更新最大值和子集个数。代码Python3class Solution: def countMaxOrSubsets(self, nums: List[int]) - int: maxOr, cnt 0, 0 def dfs(pos: int, orVal: int) - None: if pos len(nums): nonlocal maxOr, cnt if orVal maxOr: maxOr, cnt orVal, 1 elif orVal maxOr: cnt 1 return dfs(pos 1, orVal | nums[pos]) dfs(pos 1, orVal) dfs(0, 0) return cntJavaclass Solution { int[] nums; int maxOr, cnt; public int countMaxOrSubsets(int[] nums) { this.nums nums; this.maxOr 0; this.cnt 0; dfs(0, 0); return cnt; } public void dfs(int pos, int orVal) { if (pos nums.length) { if (orVal maxOr) { maxOr orVal; cnt 1; } else if (orVal maxOr) { cnt; } return; } dfs(pos 1, orVal | nums[pos]); dfs(pos 1, orVal); } }C#public class Solution { int[] nums; int maxOr, cnt; public int CountMaxOrSubsets(int[] nums) { this.nums nums; this.maxOr 0; this.cnt 0; DFS(0, 0); return cnt; } public void DFS(int pos, int orVal) { if (pos nums.Length) { if (orVal maxOr) { maxOr orVal; cnt 1; } else if (orVal maxOr) { cnt; } return; } DFS(pos 1, orVal | nums[pos]); DFS(pos 1, orVal); } }Cclass Solution { public: int countMaxOrSubsets(vectorint nums) { this-nums nums; this-maxOr 0; this-cnt 0; dfs(0, 0); return cnt; } void dfs(int pos, int orVal) { if (pos nums.size()) { if (orVal maxOr) { maxOr orVal; cnt 1; } else if (orVal maxOr) { cnt; } return; } dfs(pos 1, orVal| nums[pos]); dfs(pos 1, orVal); } private: vectorint nums; int maxOr, cnt; };Cvoid dfs(int pos, int orVal, const int* nums, int numsSize, int* maxOr, int* cnt) { if (pos numsSize) { if (orVal *maxOr) { *maxOr orVal; *cnt 1; } else if (orVal *maxOr) { (*cnt); } return; } dfs(pos 1, orVal | nums[pos], nums, numsSize, maxOr, cnt); dfs(pos 1, orVal, nums, numsSize, maxOr, cnt); } int countMaxOrSubsets(int* nums, int numsSize) { int cnt 0; int maxOr 0; dfs(0, 0, nums, numsSize, maxOr, cnt); return cnt; }复杂度分析时间复杂度O(2n) 其中 n 是数组 nums 的长度。状态数一共有 O(20 21 ... 2n) O(2×2n) O(2n) 种每次计算只消耗常数时间。空间复杂度O(n) 其中 n 是数组 nums 的长度。搜索深度最多为 n 。

相关新闻

最新新闻

为什么你的AI工具总在“假装高效”?深度诊断每日流程断点(附12项自检清单+热力图分析法)

为什么你的AI工具总在“假装高效”?深度诊断每日流程断点(附12项自检清单+热力图分析法)

更多请点击: https://kaifayun.com 第一章:AI工具“假装高效”的本质悖论 当开发者在终端中键入 copilot suggest --file main.py,IDE 瞬间补全 20 行函数——这看似是效率跃迁,实则常掩盖一个被忽略的代价:认知卸载…

2026/7/22 13:37:43
Mac用户必备:Termius与Cyberduck替代Xshell方案

Mac用户必备:Termius与Cyberduck替代Xshell方案

1. 为什么Mac用户需要Xshell替代品?作为长期使用Mac进行开发运维的技术从业者,我深刻理解在macOS环境下寻找优秀终端工具的痛点。Windows平台上广受好评的Xshell确实提供了SSH、FTP等一体化解决方案,但其商业授权模式(家庭/学校免…

2026/7/22 13:37:43
前后端分离架构演进与性能优化实战

前后端分离架构演进与性能优化实战

1. 前后端分离的本质与演进路径 前后端分离并非简单的技术选型问题,而是软件开发模式的一次深刻变革。在传统MVC架构中,JSP等模板技术将前后端代码强耦合在一起,导致前端开发者需要理解Java代码,后端工程师则被迫处理页面样式问题…

2026/7/22 13:37:43
程序员成长必备:开发工具、学习资料与效率神器全指南

程序员成长必备:开发工具、学习资料与效率神器全指南

1. 程序员成长路上的必备资源全景图在技术这条路上摸爬滚打十几年,我深刻体会到优质资源对程序员成长的关键作用。刚开始学编程时,我总在低质量教程和过时资料上浪费大量时间,直到后来逐渐建立起自己的技术资源库。今天就把这些压箱底的宝贝整…

2026/7/22 13:37:43
大健康品牌策划的核心内容有哪些?

大健康品牌策划的核心内容有哪些?

如果你想做大健康品牌,策划的核心其实不是“卖产品”,而是“传递信任感”。大健康行业特殊,用户买的是健康、是放心、是生活方式,所以品牌策划必须从战略定位开始,然后层层落地。根据我多年的观察,核心内容…

2026/7/22 13:37:43
Kimi K3模型集成实战:应对高并发与长文本处理的基础设施挑战

Kimi K3模型集成实战:应对高并发与长文本处理的基础设施挑战

这次我们来看一个很有意思的现象:Kimi K3 模型在 OpenRouter 平台上上线仅 2 天,就迅速冲到了平台第 10 大模型的位置,但随之而来的是基础设施不堪重负的问题。这个案例不仅反映了当前 AI 模型服务的火爆程度,也暴露了大规模模型部…

2026/7/22 13:32:43

月新闻