问题是找到给定数组的所有子数组,并将其所有元素的xor等于零。
例如,如果数组包含元素[13,8,5,3,3]
,则解决方案应提供所有0-2
,3-4
,0-4
等子数组的索引。
问题类似于被问到的here
唯一的区别是我希望所有满足方程A0 xor A1 xor...xor An = 0
的子数组的索引
答案 0 :(得分:2)
这是链接问题的相当简单的扩展。在Python中,
# Multivalued map from the XOR of array[:i] to i for all i.
prefix_xor_to_stops = {0: [0]}
prefix_xor = 0
for j, x in range(array):
prefix_xor ^= x
# Returns the value associated with prefix_xor. Inserts [] if not present.
stops = prefix_xor_to_stops.setdefault(prefix_xor, [])
for i in stops:
yield (i, j+1)
stops.append(j+1)
和以前一样,想法是子数组array[i:j]
的XOR为零,且仅当array[:i]
的XOR等于array[:j]
的XOR时。对于数组的每个后续元素,我们从在上一个元素结束的前缀的XOR计算在该元素结束的前缀的XOR,然后查找上述方程式的所有解i
。然后,我们插入新的关联并继续。
答案 1 :(得分:2)
如果您想修改帖子中提到的答案,那么我希望您对这个解决方案非常了解。 现在,该解决方案缺少的是它仅存储特定前缀xor和的第一个索引出现。不会跟踪发生相同xorSum的其他索引。因此,您需要做的是修改映射以为每个xorSum保留一个索引列表(C ++中的向量)。
答案 2 :(得分:1)
如果数组的两个不同前缀的xor相等,则假设长度为x1的前缀和长度为x2的前缀,则从x1 +1到x2的子数组的xor等于0。创建一个字典(BST,哈希表) ,类似的东西)并在那里存储对(前缀和值,即给出该值的前缀)。具有相同值的任何两个元素将为您提供一个子数组。您也可以根据需要使用Trie查找它。
使用Trie:
在开始时,Trie由单个节点组成,没有边缘。我们要添加数字。为它们建立索引也很方便,因为我们要查找所有子数组。在Trie中代表某些数字(在重复的情况下为多个)的每个节点将存储其索引列表,因此我们可以轻松获得子数组。
当我们将数字n与索引i相加时,我们将n写为二进制数。我们从初始节点开始。如果n的最高有效位等于0,如果从开始就存在标记为0的边,那么我们将移至相应的顶点;如果不存在,则创建指向0的新边指向新节点,然后将其移至新创建的边。一个(与1相同)。然后我们继续这样做,直到遍历n的每一位为止。我们将索引i添加到最终到达的节点中的索引列表中。
总复杂度为O(n * log(数组中的最大值))
它可能不会比使用BST或哈希数组更好,但它是一个流行的技巧,尤其在XOR操作的某些问题上很有用。
答案 3 :(得分:1)
我将在Python 3.7中编写代码块
让我成为(i,j)的元组列表
处理问题的最有效,最简单的方法是:
步骤1:计算前缀的异或:
xorArr[0] = arr[0] #here arr = [13,8,5,3,3]
for i in range(1, n):
xorArr[i] = xorArr[i - 1] ^ arr[i]
第2步:检查xorArr [i] = 0是否在任意点,如果是,则arr [:i + 1]是一个xor为零的子数组:
for i in range(1, n):
xorArr[i] = xorArr[i - 1] ^ arr[i]
if xorArr[i]==0:
l.append((0,i))
第3步:现在制作一个字典来存储xorArr中出现的每个元素的索引列表
d = {xorArr[0]:[0]}
for x in range(1,n):
if xorArr[x] in d.keys():
d[xorArr[x]].append(x)
else:
d[xorArr[x]] = [x]
第4步:创建一个函数,将d [xorArr [x]]中的每个元素配对(i,j)并将其添加到l:
from itertools import combinations
def pair_up(arr):
return list(combinations(arr,2))
for x in d.values():
if len(x)==1: #you don't have to worry about elements that occur only once
continue
else: # if same element is present at i and j (i<j) then
l+=pair_up(x) # all pairs of (i,j) are valid (xor(arr[i:j]) = 0)
P.S:您不必担心排序,因为d中的所有值显然都会被排序。希望这可以帮助。 做投票。干杯!
编辑:
代码的复杂度:O(n *((xorArr中具有最大频率的元素的频率选择2))或O(n *(max_freq C 2))。