Skip to content

Files

Latest commit

c29b144 · May 17, 2024

History

History

2044.Count Number of Maximum Bitwise-OR Subsets

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
May 17, 2024
May 17, 2024
Aug 13, 2022
Oct 17, 2021
Oct 17, 2021
Oct 17, 2021
Mar 15, 2022
Dec 24, 2021
Jan 13, 2024
Jan 13, 2024
Jan 13, 2024
Jan 13, 2024
Jan 13, 2024
Jan 13, 2024
Jan 13, 2024
Jan 13, 2024
Jan 13, 2024
comments difficulty edit_url rating source tags
true
中等
1567
第 263 场周赛 Q3
位运算
数组
回溯
枚举

English Version

题目描述

给你一个整数数组 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] <= 105

解法

方法一:DFS

简单 DFS。可以预先算出按位或的最大值 mx,然后 DFS 搜索按位或结果等于 mx 的所有子集数。也可以在 DFS 搜索中逐渐更新 mx 与对应的子集数。

时间复杂度 O ( 2 n )

Python3

class Solution:
    def countMaxOrSubsets(self, nums: List[int]) -> int:
        mx = ans = 0
        for x in nums:
            mx |= x

        def dfs(i, t):
            nonlocal mx, ans
            if i == len(nums):
                if t == mx:
                    ans += 1
                return
            dfs(i + 1, t)
            dfs(i + 1, t | nums[i])

        dfs(0, 0)
        return ans

Java

class Solution {
    private int mx;
    private int ans;
    private int[] nums;

    public int countMaxOrSubsets(int[] nums) {
        mx = 0;
        for (int x : nums) {
            mx |= x;
        }
        this.nums = nums;
        dfs(0, 0);
        return ans;
    }

    private void dfs(int i, int t) {
        if (i == nums.length) {
            if (t == mx) {
                ++ans;
            }
            return;
        }
        dfs(i + 1, t);
        dfs(i + 1, t | nums[i]);
    }
}

C++

class Solution {
public:
    int mx;
    int ans;
    vector<int> nums;

    int countMaxOrSubsets(vector<int>& nums) {
        this->nums = nums;
        mx = 0;
        ans = 0;
        for (int x : nums) mx |= x;
        dfs(0, 0);
        return ans;
    }

    void dfs(int i, int t) {
        if (i == nums.size()) {
            if (t == mx) ++ans;
            return;
        }
        dfs(i + 1, t);
        dfs(i + 1, t | nums[i]);
    }
};

Go

func countMaxOrSubsets(nums []int) int {
	mx, ans := 0, 0
	for _, x := range nums {
		mx |= x
	}

	var dfs func(i, t int)
	dfs = func(i, t int) {
		if i == len(nums) {
			if t == mx {
				ans++
			}
			return
		}
		dfs(i+1, t)
		dfs(i+1, t|nums[i])
	}

	dfs(0, 0)
	return ans
}

TypeScript

function countMaxOrSubsets(nums: number[]): number {
    let n = nums.length;
    let max = 0;
    for (let i = 0; i < n; i++) {
        max |= nums[i];
    }
    let ans = 0;
    function dfs(pre: number, depth: number): void {
        if (depth == n) {
            if (pre == max) ++ans;
            return;
        }
        dfs(pre, depth + 1);
        dfs(pre | nums[depth], depth + 1);
    }
    dfs(0, 0);
    return ans;
}

Rust

impl Solution {
    fn dfs(nums: &Vec<i32>, i: usize, sum: i32) -> (i32, i32) {
        let n = nums.len();
        let mut max = i32::MIN;
        let mut res = 0;
        for j in i..n {
            let num = sum | nums[j];
            if num >= max {
                if num > max {
                    max = num;
                    res = 0;
                }
                res += 1;
            }
            let (r_max, r_res) = Self::dfs(nums, j + 1, num);
            if r_max >= max {
                if r_max > max {
                    max = r_max;
                    res = 0;
                }
                res += r_res;
            }
        }
        (max, res)
    }

    pub fn count_max_or_subsets(nums: Vec<i32>) -> i32 {
        Self::dfs(&nums, 0, 0).1
    }
}

方法二:二进制枚举

时间复杂度 O ( n 2 n )

Python3

class Solution:
    def countMaxOrSubsets(self, nums: List[int]) -> int:
        def dfs(u, t):
            nonlocal ans, mx
            if u == len(nums):
                if t > mx:
                    mx, ans = t, 1
                elif t == mx:
                    ans += 1
                return
            dfs(u + 1, t | nums[u])
            dfs(u + 1, t)

        ans = mx = 0
        dfs(0, 0)
        return ans

Java

class Solution {
    private int mx;
    private int ans;
    private int[] nums;

    public int countMaxOrSubsets(int[] nums) {
        this.nums = nums;
        dfs(0, 0);
        return ans;
    }

    private void dfs(int u, int t) {
        if (u == nums.length) {
            if (t > mx) {
                mx = t;
                ans = 1;
            } else if (t == mx) {
                ++ans;
            }
            return;
        }
        dfs(u + 1, t);
        dfs(u + 1, t | nums[u]);
    }
}

C++

class Solution {
public:
    int mx;
    int ans;

    int countMaxOrSubsets(vector<int>& nums) {
        dfs(0, 0, nums);
        return ans;
    }

    void dfs(int u, int t, vector<int>& nums) {
        if (u == nums.size()) {
            if (t > mx) {
                mx = t;
                ans = 1;
            } else if (t == mx)
                ++ans;
            return;
        }
        dfs(u + 1, t, nums);
        dfs(u + 1, t | nums[u], nums);
    }
};

Go

func countMaxOrSubsets(nums []int) int {
	n := len(nums)
	ans := 0
	mx := 0
	for mask := 1; mask < 1<<n; mask++ {
		t := 0
		for i, v := range nums {
			if ((mask >> i) & 1) == 1 {
				t |= v
			}
		}
		if mx < t {
			mx = t
			ans = 1
		} else if mx == t {
			ans++
		}
	}
	return ans
}

TypeScript

function countMaxOrSubsets(nums: number[]): number {
    const n = nums.length;
    let res = 0;
    let max = -Infinity;
    const dfs = (i: number, sum: number) => {
        for (let j = i; j < n; j++) {
            const num = sum | nums[j];
            if (num >= max) {
                if (num > max) {
                    max = num;
                    res = 0;
                }
                res++;
            }
            dfs(j + 1, num);
        }
    };
    dfs(0, 0);

    return res;
}

方法三

Python3

class Solution:
    def countMaxOrSubsets(self, nums: List[int]) -> int:
        n = len(nums)
        ans = 0
        mx = 0
        for mask in range(1 << n):
            t = 0
            for i, v in enumerate(nums):
                if (mask >> i) & 1:
                    t |= v
            if mx < t:
                mx = t
                ans = 1
            elif mx == t:
                ans += 1
        return ans

Java

class Solution {
    public int countMaxOrSubsets(int[] nums) {
        int n = nums.length;
        int ans = 0;
        int mx = 0;
        for (int mask = 1; mask < 1 << n; ++mask) {
            int t = 0;
            for (int i = 0; i < n; ++i) {
                if (((mask >> i) & 1) == 1) {
                    t |= nums[i];
                }
            }
            if (mx < t) {
                mx = t;
                ans = 1;
            } else if (mx == t) {
                ++ans;
            }
        }
        return ans;
    }
}

C++

class Solution {
public:
    int countMaxOrSubsets(vector<int>& nums) {
        int n = nums.size();
        int ans = 0;
        int mx = 0;
        for (int mask = 1; mask < 1 << n; ++mask) {
            int t = 0;
            for (int i = 0; i < n; ++i) {
                if ((mask >> i) & 1) {
                    t |= nums[i];
                }
            }
            if (mx < t) {
                mx = t;
                ans = 1;
            } else if (mx == t)
                ++ans;
        }
        return ans;
    }
};

Go

func countMaxOrSubsets(nums []int) int {
	mx, ans := 0, 0
	var dfs func(u, t int)
	dfs = func(u, t int) {
		if u == len(nums) {
			if t > mx {
				mx, ans = t, 1
			} else if t == mx {
				ans++
			}
			return
		}
		dfs(u+1, t)
		dfs(u+1, t|nums[u])
	}
	dfs(0, 0)
	return ans
}