子陣列異或和為0的最多劃分
阿新 • • 發佈:2021-02-01
技術標籤:資料結構與演算法動態規劃資料結構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是滿足這個條件的最後一個位置。
程式碼
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]);
}
}