跳转至

3287. 求出数组中最大序列值

题目描述

给你一个整数数组 nums 和一个  整数 k 。

定义长度为 2 * x 的序列 seq 的  为:

  • (seq[0] OR seq[1] OR ... OR seq[x - 1]) XOR (seq[x] OR seq[x + 1] OR ... OR seq[2 * x - 1]).

请你求出 nums 中所有长度为 2 * k 的 子序列最大值 。

 

示例 1:

输入:nums = [2,6,7], k = 1

输出:5

解释:

子序列 [2, 7] 的值最大,为 2 XOR 7 = 5 。

示例 2:

输入:nums = [4,2,5,6,7], k = 2

输出:2

解释:

子序列 [4, 5, 6, 7] 的值最大,为 (4 OR 5) XOR (6 OR 7) = 2 。

 

提示:

  • 2 <= nums.length <= 400
  • 1 <= nums[i] < 27
  • 1 <= k <= nums.length / 2

解法

方法一:动态规划 + 前后缀分解 + 枚举

我们考虑将序列分成两部分,前 $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$。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
class Solution {
public:
    int maxValue(vector<int>& nums, int k) {
        int m = 1 << 7;
        int n = nums.size();

        vector<vector<vector<bool>>> f(n + 1, vector<vector<bool>>(k + 2, vector<bool>(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<vector<vector<bool>>> g(n + 1, vector<vector<bool>>(k + 2, vector<bool>(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;
    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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;
}

评论