算法leetcode每日一练2044. 统计按位或能得到最大值的子集数目

Posted 二当家的白帽子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法leetcode每日一练2044. 统计按位或能得到最大值的子集数目相关的知识,希望对你有一定的参考价值。


文章目录


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

给你一个整数数组 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 <= nums.length <= 16
  • 1 <= nums[i] <= 1 0 5 10^5 105

分析

  • 面对这道算法题目,二当家的陷入了沉思。
  • 深度优先,递归套娃大法。
  • 每个数字可以选择或者不选择。
  • 如果先找按位或能得到的最大值,再计数需要多次遍历;事实上可以一次搞定。

题解

java

class Solution 
    public int countMaxOrSubsets(int[] nums) 
        int[] arr = new int[2];
		dfs(nums, 0, 0, arr);
		return arr[1];
	

	private void dfs(int[] nums, int pos, int curVal, int[] arr) 
		if (pos == nums.length) 
			if (curVal > arr[0]) 
				arr[0] = curVal;
				arr[1] = 1;
			 else if (curVal == arr[0]) 
				++arr[1];
			
		 else 
			// 不选当前数字
			dfs(nums, pos + 1, curVal, arr);
			// 选择当前数字
			dfs(nums, pos + 1, curVal | nums[pos], arr);
		
	


c

void dfs(int* nums, int numsSize, int pos, int curVal, int* maxVal, int* maxValCnt) 
    if (pos == numsSize) 
        if (curVal > *maxVal) 
            *maxVal = curVal;
            *maxValCnt = 1;
         else if (curVal == *maxVal) 
            ++*maxValCnt;
        
     else 
        // 不选当前数字
        dfs(nums, numsSize, pos + 1, curVal, maxVal, maxValCnt);
        // 选择当前数字
        dfs(nums, numsSize, pos + 1, curVal | nums[pos], maxVal, maxValCnt);
    


int countMaxOrSubsets(int* nums, int numsSize)
    int maxVal = 0;
    int maxValCnt = 0;
    dfs(nums, numsSize, 0, 0, &maxVal, &maxValCnt);
    return maxValCnt;


c++

class Solution 
    void dfs(vector<int>& nums, int pos, int curVal, int& maxVal, int& maxValCnt) 
        if (pos == nums.size()) 
            if (curVal > maxVal) 
                maxVal = curVal;
                maxValCnt = 1;
             else if (curVal == maxVal) 
                ++maxValCnt;
            
         else 
            // 不选当前数字
            dfs(nums, pos + 1, curVal, maxVal, maxValCnt);
            // 选择当前数字
            dfs(nums, pos + 1, curVal | nums[pos], maxVal, maxValCnt);
        
    
public:
    int countMaxOrSubsets(vector<int>& nums) 
        int maxVal = 0;
        int maxValCnt = 0;
        dfs(nums, 0, 0, maxVal, maxValCnt);
        return maxValCnt;
    
;

python

class Solution:
    def countMaxOrSubsets(self, nums: List[int]) -> int:
        def dfs(pos: int, cur_val: int):
            if pos == len(nums):
                nonlocal max_val, max_val_cnt
                if cur_val > max_val:
                    max_val = cur_val
                    max_val_cnt = 1
                elif cur_val == max_val:
                    max_val_cnt += 1
            else:
                # 不选当前数字
                dfs(pos + 1, cur_val)
                # 选择当前数字
                dfs(pos + 1, cur_val | nums[pos])
        max_val = 0
        max_val_cnt = 0
        dfs(0, 0)
        return max_val_cnt
        

go

func countMaxOrSubsets(nums []int) int 
    maxVal := 0
	maxValCnt := 0
	var dfs func(int, int)
	dfs = func(pos, curVal int) 
		if pos == len(nums) 
			if curVal > maxVal 
				maxVal = curVal
				maxValCnt = 1
			 else if curVal == maxVal 
				maxValCnt++
			
		 else 
			// 不选当前数字
			dfs(pos + 1, curVal)
			// 选择当前数字
			dfs(pos + 1, curVal|nums[pos])
		
	
	dfs(0, 0)
	return maxValCnt


rust

impl Solution 
    pub fn count_max_or_subsets(nums: Vec<i32>) -> i32 
        fn dfs(nums: &Vec<i32>, pos: usize, curVal: i32, maxVal: &mut i32, maxValCnt: &mut i32) 
            if pos == nums.len() 
                if curVal > *maxVal 
                    *maxVal = curVal;
                    *maxValCnt = 1;
                 else if curVal == *maxVal 
                    *maxValCnt += 1;
                
             else 
                // 不选当前数字
                dfs(nums, pos + 1, curVal, maxVal, maxValCnt);
                // 选择当前数字
                dfs(nums, pos + 1, curVal | nums[pos], maxVal, maxValCnt);
            
        

        let mut maxVal = 0;
        let mut maxValCnt = 0;
        dfs(&nums, 0, 0, &mut maxVal, &mut maxValCnt);

        maxValCnt
    


typescript

function countMaxOrSubsets(nums: number[]): number 
    const dfs = (pos: number, curVal: number) => 
        if (pos == nums.length) 
            if (curVal > maxVal) 
                maxVal = curVal;
                maxValCnt = 1;
             else if (curVal == maxVal) 
                maxValCnt += 1;
            
         else 
            // 不选当前数字
            dfs(pos + 1, curVal);
            // 选择当前数字
            dfs(pos + 1, curVal | nums[pos]);
        
    ;

    let maxVal = 0;
    let maxValCnt = 0;
    dfs(0, 0);
    return maxValCnt;
;


原题传送门:https://leetcode.cn/problems/count-number-of-maximum-bitwise-or-subsets/


非常感谢你阅读本文~
欢迎【👍点赞】【⭐收藏】【📝评论】~
放弃不难,但坚持一定很酷~
希望我们大家都能每天进步一点点~
本文由 二当家的白帽子:https://le-yi.blog.csdn.net/ 博客原创~


以上是关于算法leetcode每日一练2044. 统计按位或能得到最大值的子集数目的主要内容,如果未能解决你的问题,请参考以下文章

leetcode中等2044. 统计按位或能得到最大值的子集数目

LeetCode 2044. 统计按位或能得到最大值的子集数目

算法leetcode每日一练2265. 统计值等于子树平均值的节点数

算法leetcode每日一练2255. 统计是给定字符串前缀的字符串数目

解题报告力扣 第 263 场周赛

算法leetcode每日一练2161. 根据给定数字划分数组