diff --git a/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/README.md b/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/README.md index a6f7ec447934c..5e449996aeb1d 100644 --- a/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/README.md +++ b/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/README.md @@ -72,32 +72,295 @@ tags: -### 方法一 +### 方法一:动态规划 + 前后缀分解 + 枚举 + +我们考虑将序列分成两部分,前 $k$ 个元素和后 $k$ 个元素,分别计算前后缀的所有可能的异或值。 + +定义 $f[i][j][x]$ 表示前 $i$ 个元素中取 $j$ 个元素,是否存在一个子集的异或值为 $x$,定义 $g[i][j][y]$ 表示从下标 $i$ 开始取 $j$ 个元素,是否存在一个子集的异或值为 $y$。 + +考虑 $f[i][j][x]$ 的转移方程,对于第 $i$ 个元素(从 $0$ 开始),我们可以选择不取,也可以选择取,因此有: + +$$ +f[i + 1][j][x] = f[i + 1][j][x] \lor f[i][j][x] \\ +f[i + 1][j + 1][x \lor \text{nums}[i]] = f[i + 1][j + 1][x \lor \text{nums}[i]] \lor f[i][j][x] +$$ + +对于 $g[i][j][y]$ 的转移方程,同样对于第 $i$ 个元素(从 $n - 1$ 开始),我们可以选择不取,也可以选择取,因此有: + +$$ +g[i - 1][j][y] = g[i - 1][j][y] \lor g[i][j][y] \\ +g[i - 1][j + 1][y \lor \text{nums}[i - 1]] = g[i - 1][j + 1][y \lor \text{nums}[i - 1]] \lor g[i][j][y] +$$ + +最后,我们在 $[k, n - k]$ 的范围内枚举 $i$,对于每一个 $i$,我们枚举 $x$ 和 $y$,其中 $0 \leq x, y < 2^7$,如果 $f[i][k][x]$ 和 $g[i][k][y]$ 均为真,那么我们更新答案 $\text{ans} = \max(\text{ans}, x \oplus y)$。 + +时间复杂度 $O(n \times m \times k)$,空间复杂度 $O(n \times m \times k)$,其中 $n$ 为数组长度,而 $m = 2^7$。 #### Python3 ```python - +class Solution: + def maxValue(self, nums: List[int], k: int) -> int: + m = 1 << 7 + n = len(nums) + f = [[[False] * m for _ in range(k + 2)] for _ in range(n + 1)] + f[0][0][0] = True + for i in range(n): + for j in range(k + 1): + for x in range(m): + f[i + 1][j][x] |= f[i][j][x] + f[i + 1][j + 1][x | nums[i]] |= f[i][j][x] + + g = [[[False] * m for _ in range(k + 2)] for _ in range(n + 1)] + g[n][0][0] = True + for i in range(n, 0, -1): + for j in range(k + 1): + for y in range(m): + g[i - 1][j][y] |= g[i][j][y] + g[i - 1][j + 1][y | nums[i - 1]] |= g[i][j][y] + + ans = 0 + for i in range(k, n - k + 1): + for x in range(m): + if f[i][k][x]: + for y in range(m): + if g[i][k][y]: + ans = max(ans, x ^ y) + return ans ``` #### Java ```java - +class Solution { + public int maxValue(int[] nums, int k) { + int m = 1 << 7; + int n = nums.length; + boolean[][][] f = new boolean[n + 1][k + 2][m]; + f[0][0][0] = true; + + for (int i = 0; i < n; i++) { + for (int j = 0; j <= k; j++) { + for (int x = 0; x < m; x++) { + if (f[i][j][x]) { + f[i + 1][j][x] = true; + f[i + 1][j + 1][x | nums[i]] = true; + } + } + } + } + + boolean[][][] g = new boolean[n + 1][k + 2][m]; + g[n][0][0] = true; + + for (int i = n; i > 0; i--) { + for (int j = 0; j <= k; j++) { + for (int y = 0; y < m; y++) { + if (g[i][j][y]) { + g[i - 1][j][y] = true; + g[i - 1][j + 1][y | nums[i - 1]] = true; + } + } + } + } + + int ans = 0; + + for (int i = k; i <= n - k; i++) { + for (int x = 0; x < m; x++) { + if (f[i][k][x]) { + for (int y = 0; y < m; y++) { + if (g[i][k][y]) { + ans = Math.max(ans, x ^ y); + } + } + } + } + } + + return ans; + } +} ``` #### C++ ```cpp - +class Solution { +public: + int maxValue(vector& nums, int k) { + int m = 1 << 7; + int n = nums.size(); + + vector>> f(n + 1, vector>(k + 2, vector(m, false))); + f[0][0][0] = true; + + for (int i = 0; i < n; i++) { + for (int j = 0; j <= k; j++) { + for (int x = 0; x < m; x++) { + if (f[i][j][x]) { + f[i + 1][j][x] = true; + f[i + 1][j + 1][x | nums[i]] = true; + } + } + } + } + + vector>> g(n + 1, vector>(k + 2, vector(m, false))); + g[n][0][0] = true; + + for (int i = n; i > 0; i--) { + for (int j = 0; j <= k; j++) { + for (int y = 0; y < m; y++) { + if (g[i][j][y]) { + g[i - 1][j][y] = true; + g[i - 1][j + 1][y | nums[i - 1]] = true; + } + } + } + } + + int ans = 0; + + for (int i = k; i <= n - k; i++) { + for (int x = 0; x < m; x++) { + if (f[i][k][x]) { + for (int y = 0; y < m; y++) { + if (g[i][k][y]) { + ans = max(ans, x ^ y); + } + } + } + } + } + + return ans; + } +}; ``` #### Go ```go +func maxValue(nums []int, k int) int { + m := 1 << 7 + n := len(nums) + + f := make([][][]bool, n+1) + for i := range f { + f[i] = make([][]bool, k+2) + for j := range f[i] { + f[i][j] = make([]bool, m) + } + } + f[0][0][0] = true + + for i := 0; i < n; i++ { + for j := 0; j <= k; j++ { + for x := 0; x < m; x++ { + if f[i][j][x] { + f[i+1][j][x] = true + f[i+1][j+1][x|nums[i]] = true + } + } + } + } + + g := make([][][]bool, n+1) + for i := range g { + g[i] = make([][]bool, k+2) + for j := range g[i] { + g[i][j] = make([]bool, m) + } + } + g[n][0][0] = true + + for i := n; i > 0; i-- { + for j := 0; j <= k; j++ { + for y := 0; y < m; y++ { + if g[i][j][y] { + g[i-1][j][y] = true + g[i-1][j+1][y|nums[i-1]] = true + } + } + } + } + + ans := 0 + + for i := k; i <= n-k; i++ { + for x := 0; x < m; x++ { + if f[i][k][x] { + for y := 0; y < m; y++ { + if g[i][k][y] { + ans = max(ans, x^y) + } + } + } + } + } + + return ans +} +``` +#### TypeScript + +```ts +function maxValue(nums: number[], k: number): number { + const m = 1 << 7; + const n = nums.length; + + const f: boolean[][][] = Array.from({ length: n + 1 }, () => + Array.from({ length: k + 2 }, () => Array(m).fill(false)), + ); + f[0][0][0] = true; + + for (let i = 0; i < n; i++) { + for (let j = 0; j <= k; j++) { + for (let x = 0; x < m; x++) { + if (f[i][j][x]) { + f[i + 1][j][x] = true; + f[i + 1][j + 1][x | nums[i]] = true; + } + } + } + } + + const g: boolean[][][] = Array.from({ length: n + 1 }, () => + Array.from({ length: k + 2 }, () => Array(m).fill(false)), + ); + g[n][0][0] = true; + + for (let i = n; i > 0; i--) { + for (let j = 0; j <= k; j++) { + for (let y = 0; y < m; y++) { + if (g[i][j][y]) { + g[i - 1][j][y] = true; + g[i - 1][j + 1][y | nums[i - 1]] = true; + } + } + } + } + + let ans = 0; + + for (let i = k; i <= n - k; i++) { + for (let x = 0; x < m; x++) { + if (f[i][k][x]) { + for (let y = 0; y < m; y++) { + if (g[i][k][y]) { + ans = Math.max(ans, x ^ y); + } + } + } + } + } + + return ans; +} ``` diff --git a/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/README_EN.md b/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/README_EN.md index b5951471fccb3..085c5883035f8 100644 --- a/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/README_EN.md +++ b/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/README_EN.md @@ -70,32 +70,295 @@ tags: -### Solution 1 +### Solution 1: Dynamic Programming + Prefix and Suffix Decomposition + Enumeration + +We consider dividing the sequence into two parts, the first $k$ elements and the last $k$ elements, and calculate all possible XOR values for the prefixes and suffixes. + +Define $f[i][j][x]$ to represent whether there exists a subset with an XOR value of $x$ by taking $j$ elements from the first $i$ elements. Define $g[i][j][y]$ to represent whether there exists a subset with an XOR value of $y$ by taking $j$ elements starting from index $i$. + +Consider the transition equation for $f[i][j][x]$. For the $i$-th element (starting from $0$), we can choose to take it or not, so we have: + +$$ +f[i + 1][j][x] = f[i + 1][j][x] \lor f[i][j][x] \\ +f[i + 1][j + 1][x \lor \text{nums}[i]] = f[i + 1][j + 1][x \lor \text{nums}[i]] \lor f[i][j][x] +$$ + +For the transition equation of $g[i][j][y]$, similarly for the $i$-th element (starting from $n - 1$), we can choose to take it or not, so we have: + +$$ +g[i - 1][j][y] = g[i - 1][j][y] \lor g[i][j][y] \\ +g[i - 1][j + 1][y \lor \text{nums}[i - 1]] = g[i - 1][j + 1][y \lor \text{nums}[i - 1]] \lor g[i][j][y] +$$ + +Finally, we enumerate $i$ in the range $[k, n - k]$. For each $i$, we enumerate $x$ and $y$, where $0 \leq x, y < 2^7$. If both $f[i][k][x]$ and $g[i][k][y]$ are true, we update the answer $\text{ans} = \max(\text{ans}, x \oplus y)$. + +The time complexity is $O(n \times m \times k)$, and the space complexity is $O(n \times m \times k)$, where $n$ is the length of the array, and $m = 2^7$. #### Python3 ```python - +class Solution: + def maxValue(self, nums: List[int], k: int) -> int: + m = 1 << 7 + n = len(nums) + f = [[[False] * m for _ in range(k + 2)] for _ in range(n + 1)] + f[0][0][0] = True + for i in range(n): + for j in range(k + 1): + for x in range(m): + f[i + 1][j][x] |= f[i][j][x] + f[i + 1][j + 1][x | nums[i]] |= f[i][j][x] + + g = [[[False] * m for _ in range(k + 2)] for _ in range(n + 1)] + g[n][0][0] = True + for i in range(n, 0, -1): + for j in range(k + 1): + for y in range(m): + g[i - 1][j][y] |= g[i][j][y] + g[i - 1][j + 1][y | nums[i - 1]] |= g[i][j][y] + + ans = 0 + for i in range(k, n - k + 1): + for x in range(m): + if f[i][k][x]: + for y in range(m): + if g[i][k][y]: + ans = max(ans, x ^ y) + return ans ``` #### Java ```java - +class Solution { + public int maxValue(int[] nums, int k) { + int m = 1 << 7; + int n = nums.length; + boolean[][][] f = new boolean[n + 1][k + 2][m]; + f[0][0][0] = true; + + for (int i = 0; i < n; i++) { + for (int j = 0; j <= k; j++) { + for (int x = 0; x < m; x++) { + if (f[i][j][x]) { + f[i + 1][j][x] = true; + f[i + 1][j + 1][x | nums[i]] = true; + } + } + } + } + + boolean[][][] g = new boolean[n + 1][k + 2][m]; + g[n][0][0] = true; + + for (int i = n; i > 0; i--) { + for (int j = 0; j <= k; j++) { + for (int y = 0; y < m; y++) { + if (g[i][j][y]) { + g[i - 1][j][y] = true; + g[i - 1][j + 1][y | nums[i - 1]] = true; + } + } + } + } + + int ans = 0; + + for (int i = k; i <= n - k; i++) { + for (int x = 0; x < m; x++) { + if (f[i][k][x]) { + for (int y = 0; y < m; y++) { + if (g[i][k][y]) { + ans = Math.max(ans, x ^ y); + } + } + } + } + } + + return ans; + } +} ``` #### C++ ```cpp - +class Solution { +public: + int maxValue(vector& nums, int k) { + int m = 1 << 7; + int n = nums.size(); + + vector>> f(n + 1, vector>(k + 2, vector(m, false))); + f[0][0][0] = true; + + for (int i = 0; i < n; i++) { + for (int j = 0; j <= k; j++) { + for (int x = 0; x < m; x++) { + if (f[i][j][x]) { + f[i + 1][j][x] = true; + f[i + 1][j + 1][x | nums[i]] = true; + } + } + } + } + + vector>> g(n + 1, vector>(k + 2, vector(m, false))); + g[n][0][0] = true; + + for (int i = n; i > 0; i--) { + for (int j = 0; j <= k; j++) { + for (int y = 0; y < m; y++) { + if (g[i][j][y]) { + g[i - 1][j][y] = true; + g[i - 1][j + 1][y | nums[i - 1]] = true; + } + } + } + } + + int ans = 0; + + for (int i = k; i <= n - k; i++) { + for (int x = 0; x < m; x++) { + if (f[i][k][x]) { + for (int y = 0; y < m; y++) { + if (g[i][k][y]) { + ans = max(ans, x ^ y); + } + } + } + } + } + + return ans; + } +}; ``` #### Go ```go +func maxValue(nums []int, k int) int { + m := 1 << 7 + n := len(nums) + + f := make([][][]bool, n+1) + for i := range f { + f[i] = make([][]bool, k+2) + for j := range f[i] { + f[i][j] = make([]bool, m) + } + } + f[0][0][0] = true + + for i := 0; i < n; i++ { + for j := 0; j <= k; j++ { + for x := 0; x < m; x++ { + if f[i][j][x] { + f[i+1][j][x] = true + f[i+1][j+1][x|nums[i]] = true + } + } + } + } + + g := make([][][]bool, n+1) + for i := range g { + g[i] = make([][]bool, k+2) + for j := range g[i] { + g[i][j] = make([]bool, m) + } + } + g[n][0][0] = true + + for i := n; i > 0; i-- { + for j := 0; j <= k; j++ { + for y := 0; y < m; y++ { + if g[i][j][y] { + g[i-1][j][y] = true + g[i-1][j+1][y|nums[i-1]] = true + } + } + } + } + + ans := 0 + + for i := k; i <= n-k; i++ { + for x := 0; x < m; x++ { + if f[i][k][x] { + for y := 0; y < m; y++ { + if g[i][k][y] { + ans = max(ans, x^y) + } + } + } + } + } + + return ans +} +``` +#### TypeScript + +```ts +function maxValue(nums: number[], k: number): number { + const m = 1 << 7; + const n = nums.length; + + const f: boolean[][][] = Array.from({ length: n + 1 }, () => + Array.from({ length: k + 2 }, () => Array(m).fill(false)), + ); + f[0][0][0] = true; + + for (let i = 0; i < n; i++) { + for (let j = 0; j <= k; j++) { + for (let x = 0; x < m; x++) { + if (f[i][j][x]) { + f[i + 1][j][x] = true; + f[i + 1][j + 1][x | nums[i]] = true; + } + } + } + } + + const g: boolean[][][] = Array.from({ length: n + 1 }, () => + Array.from({ length: k + 2 }, () => Array(m).fill(false)), + ); + g[n][0][0] = true; + + for (let i = n; i > 0; i--) { + for (let j = 0; j <= k; j++) { + for (let y = 0; y < m; y++) { + if (g[i][j][y]) { + g[i - 1][j][y] = true; + g[i - 1][j + 1][y | nums[i - 1]] = true; + } + } + } + } + + let ans = 0; + + for (let i = k; i <= n - k; i++) { + for (let x = 0; x < m; x++) { + if (f[i][k][x]) { + for (let y = 0; y < m; y++) { + if (g[i][k][y]) { + ans = Math.max(ans, x ^ y); + } + } + } + } + } + + return ans; +} ``` diff --git a/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/Solution.cpp b/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/Solution.cpp new file mode 100644 index 0000000000000..bd83af7cf06c2 --- /dev/null +++ b/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/Solution.cpp @@ -0,0 +1,51 @@ +class Solution { +public: + int maxValue(vector& nums, int k) { + int m = 1 << 7; + int n = nums.size(); + + vector>> f(n + 1, vector>(k + 2, vector(m, false))); + f[0][0][0] = true; + + for (int i = 0; i < n; i++) { + for (int j = 0; j <= k; j++) { + for (int x = 0; x < m; x++) { + if (f[i][j][x]) { + f[i + 1][j][x] = true; + f[i + 1][j + 1][x | nums[i]] = true; + } + } + } + } + + vector>> g(n + 1, vector>(k + 2, vector(m, false))); + g[n][0][0] = true; + + for (int i = n; i > 0; i--) { + for (int j = 0; j <= k; j++) { + for (int y = 0; y < m; y++) { + if (g[i][j][y]) { + g[i - 1][j][y] = true; + g[i - 1][j + 1][y | nums[i - 1]] = true; + } + } + } + } + + int ans = 0; + + for (int i = k; i <= n - k; i++) { + for (int x = 0; x < m; x++) { + if (f[i][k][x]) { + for (int y = 0; y < m; y++) { + if (g[i][k][y]) { + ans = max(ans, x ^ y); + } + } + } + } + } + + return ans; + } +}; diff --git a/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/Solution.go b/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/Solution.go new file mode 100644 index 0000000000000..a3376fde03e61 --- /dev/null +++ b/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/Solution.go @@ -0,0 +1,60 @@ +func maxValue(nums []int, k int) int { + m := 1 << 7 + n := len(nums) + + f := make([][][]bool, n+1) + for i := range f { + f[i] = make([][]bool, k+2) + for j := range f[i] { + f[i][j] = make([]bool, m) + } + } + f[0][0][0] = true + + for i := 0; i < n; i++ { + for j := 0; j <= k; j++ { + for x := 0; x < m; x++ { + if f[i][j][x] { + f[i+1][j][x] = true + f[i+1][j+1][x|nums[i]] = true + } + } + } + } + + g := make([][][]bool, n+1) + for i := range g { + g[i] = make([][]bool, k+2) + for j := range g[i] { + g[i][j] = make([]bool, m) + } + } + g[n][0][0] = true + + for i := n; i > 0; i-- { + for j := 0; j <= k; j++ { + for y := 0; y < m; y++ { + if g[i][j][y] { + g[i-1][j][y] = true + g[i-1][j+1][y|nums[i-1]] = true + } + } + } + } + + ans := 0 + + for i := k; i <= n-k; i++ { + for x := 0; x < m; x++ { + if f[i][k][x] { + for y := 0; y < m; y++ { + if g[i][k][y] { + ans = max(ans, x^y) + } + } + } + } + } + + return ans +} diff --git a/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/Solution.java b/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/Solution.java new file mode 100644 index 0000000000000..c337b5eb5f039 --- /dev/null +++ b/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/Solution.java @@ -0,0 +1,49 @@ +class Solution { + public int maxValue(int[] nums, int k) { + int m = 1 << 7; + int n = nums.length; + boolean[][][] f = new boolean[n + 1][k + 2][m]; + f[0][0][0] = true; + + for (int i = 0; i < n; i++) { + for (int j = 0; j <= k; j++) { + for (int x = 0; x < m; x++) { + if (f[i][j][x]) { + f[i + 1][j][x] = true; + f[i + 1][j + 1][x | nums[i]] = true; + } + } + } + } + + boolean[][][] g = new boolean[n + 1][k + 2][m]; + g[n][0][0] = true; + + for (int i = n; i > 0; i--) { + for (int j = 0; j <= k; j++) { + for (int y = 0; y < m; y++) { + if (g[i][j][y]) { + g[i - 1][j][y] = true; + g[i - 1][j + 1][y | nums[i - 1]] = true; + } + } + } + } + + int ans = 0; + + for (int i = k; i <= n - k; i++) { + for (int x = 0; x < m; x++) { + if (f[i][k][x]) { + for (int y = 0; y < m; y++) { + if (g[i][k][y]) { + ans = Math.max(ans, x ^ y); + } + } + } + } + } + + return ans; + } +} diff --git a/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/Solution.py b/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/Solution.py new file mode 100644 index 0000000000000..eda9a3cc48046 --- /dev/null +++ b/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/Solution.py @@ -0,0 +1,28 @@ +class Solution: + def maxValue(self, nums: List[int], k: int) -> int: + m = 1 << 7 + n = len(nums) + f = [[[False] * m for _ in range(k + 2)] for _ in range(n + 1)] + f[0][0][0] = True + for i in range(n): + for j in range(k + 1): + for x in range(m): + f[i + 1][j][x] |= f[i][j][x] + f[i + 1][j + 1][x | nums[i]] |= f[i][j][x] + + g = [[[False] * m for _ in range(k + 2)] for _ in range(n + 1)] + g[n][0][0] = True + for i in range(n, 0, -1): + for j in range(k + 1): + for y in range(m): + g[i - 1][j][y] |= g[i][j][y] + g[i - 1][j + 1][y | nums[i - 1]] |= g[i][j][y] + + ans = 0 + for i in range(k, n - k + 1): + for x in range(m): + if f[i][k][x]: + for y in range(m): + if g[i][k][y]: + ans = max(ans, x ^ y) + return ans diff --git a/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/Solution.ts b/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/Solution.ts new file mode 100644 index 0000000000000..953ee97ffd7dc --- /dev/null +++ b/solution/3200-3299/3287.Find the Maximum Sequence Value of Array/Solution.ts @@ -0,0 +1,52 @@ +function maxValue(nums: number[], k: number): number { + const m = 1 << 7; + const n = nums.length; + + const f: boolean[][][] = Array.from({ length: n + 1 }, () => + Array.from({ length: k + 2 }, () => Array(m).fill(false)), + ); + f[0][0][0] = true; + + for (let i = 0; i < n; i++) { + for (let j = 0; j <= k; j++) { + for (let x = 0; x < m; x++) { + if (f[i][j][x]) { + f[i + 1][j][x] = true; + f[i + 1][j + 1][x | nums[i]] = true; + } + } + } + } + + const g: boolean[][][] = Array.from({ length: n + 1 }, () => + Array.from({ length: k + 2 }, () => Array(m).fill(false)), + ); + g[n][0][0] = true; + + for (let i = n; i > 0; i--) { + for (let j = 0; j <= k; j++) { + for (let y = 0; y < m; y++) { + if (g[i][j][y]) { + g[i - 1][j][y] = true; + g[i - 1][j + 1][y | nums[i - 1]] = true; + } + } + } + } + + let ans = 0; + + for (let i = k; i <= n - k; i++) { + for (let x = 0; x < m; x++) { + if (f[i][k][x]) { + for (let y = 0; y < m; y++) { + if (g[i][k][y]) { + ans = Math.max(ans, x ^ y); + } + } + } + } + } + + return ans; +}