2021-05-17:数组中所有数都异或起来的结果,叫做异或和。给定一个数组arr,可以任意切分成若干个不相交的子数组。其中一定存在一种最优方案,使得切出异或和为0的子数组最多。返回这个最多数量。

福大大 答案2021-05-17:

准备一个map,key存前缀异或和,value存数组序号。
dp[i]是0到i的异或和为0的子数组最多的数量。

代码用golang编写。代码如下:

package main

import "fmt"

func main() {
    arr := []int{3, 2, 1, 0, 0, 2, 1, 3, 3, 2, 3, 1, 0, 0, 0}
    ret := mostXor(arr)
    fmt.Println(ret)
}

// 时间复杂度O(N)的方法
func mostXor(arr []int) int {
    if len(arr) == 0 {
        return 0
    }
    N := len(arr)
    dp := make([]int, N)

    // key 某一个前缀异或和
    // value 这个前缀异或和上次出现的位置(最晚!)
    map0 := make(map[int]int)
    map0[0] = -1
    // 0~i整体的异或和
    xor := 0
    for i := 0; i < N; i++ {
        xor ^= arr[i]
        if _, ok := map0[xor]; ok { // 可能性2
            pre := map0[xor]
            if pre == -1 {
                dp[i] = 1
            } else {
                dp[i] = dp[pre] + 1
            }
        }
        if i > 0 {
            dp[i] = getMax(dp[i-1], dp[i])
        }
        map0[xor] = i
    }
    return dp[N-1]
}

func getMax(a int, b int) int {
    if a > b {
        return a
    } else {
        return b
    }
}

执行结果如下:
图片


左神java代码