1. 程式人生 > 其它 >子陣列異或和為0的最多劃分

子陣列異或和為0的最多劃分

技術標籤:資料結構與演算法動態規劃資料結構java演算法面試

題目描述

給定一個整型陣列arr,其中可能有正有負有零。你可以隨意把整個陣列切成若干個不相容的子陣列,求異或和為0的子陣列最多可能有多少個?整數異或和定義:把陣列中所有的數異或起來得到的值。

思路

參考自《程式設計師程式碼面試指南》。
1.動態規劃。dp[i]表示arr[0…i]對應的自陣列異或和為0的最多子陣列個數。考慮arr[i]所在的子陣列異或和是否為0,可以分為兩種情況:(1)arr[i]所在的子陣列異或和不為0,此時dp[i] = dp[i-1]。(2)arr[i]所載的子陣列異或和為0,此時dp[i] = dp[k]+1,其中k代表的含義是arr[0…i]的異或和等於arr[0…k]的異或和,且k是滿足這個條件的最後一個位置。

2.針對上述的第二種情況,應該用map儲存鍵值對(異或和,最後出現的下標)。注意初始化map.put(0,-1)。

程式碼

import java.util.Scanner;
import java.util.HashMap;
public class Main{
    public static void main(String []args){
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int []arr = new int [n];
        for
(int i = 0 ; i<n ; i++){ arr[i] = scanner.nextInt(); } int []dp = new int[n]; //dp[i]:arr[0...i]的子陣列異或和為0的最多子陣列個數 HashMap<Integer, Integer> map = new HashMap<>(); //key:異或和 //value:最新出現的位置 map.put(0,-1); dp[0] = arr[0] ==
0 ? 1:0; map.put(arr[0], 0); int sum = 0; for(int i = 1 ; i<n ; i++){ sum ^= arr[i]; dp[i] = dp[i-1]; if(map.containsKey(sum)){ int k = map.get(sum); dp[i]= Math.max(dp[i], (k == -1)?1:(dp[map.get(sum)]+1)); map.remove(sum); } map.put(sum, i); } System.out.println(dp[n-1]); } }