2020年5月10日 星期日

Leetcode題解 Python:Count Triplets That Can Form Two Arrays of Equal XOR

給一列整數數列,問兩相鄰的子數列XOR總值相等的個數。

今天就差這一個沒有解出來。QQ

這種在「一數列」中取「組合」做「比較」的題目,都有一個解題方向,就是用dp的觀念去保存比較值。

比較值,比較值,比較值,因為很重要,所以說三次。而且比較也要朝著在hash類內的做處理。

這一題的比較值,很明顯地就是XOR總值。

在計算XOR總值時,會選定一個區間,而這區間可能會重複計算,因此可用hashtable,dict() 保存。

因為題目所求,兩了數列一定要相鄰,如果前面是[i,j-1],後面一定從 j 開始才有符合題目所求的可能性。
而結尾落在 j-1 位置的可能有好幾個,因此DP的會到二維,DP[pos][xor],這樣才能充分保存比較值。
DP[pos][xor]是在以pos-1位置結尾的XOR之出現次數,若同值出現2次以上的話,計數也該加計相同次數。

流程


用雙迴圈去找出所有XOR總值,並順便找出在前方結尾即DP[pos]是否出現xor,若有則加DP[pos][xor],
然後把目前的XOR總值加到DP去。
Python
class Solution:
    def countTriplets(self, arr: List[int]) -> int:
	from functools import lru_cache
	from collections import defaultdict
        @lru_cache(None)
        def xor(si, ei):
            if si == ei: return 0
            ans = arr[si] ^ xor(si+1, ei)
            return ans        
        
        result = 0
        memo = defaultdict(dict)
        n = len(arr)
        for i in range(n):
            for j in range(i,n):
                val = xor(i, j+1)
                if val in memo[i]:
                    result += memo[i][val]
                memo[j+1][val] = memo[j+1].get(val,0) + 1

        return result