この種の問題について知っておくとよいデータ構造は、累積和を持つ配列です。元のシリーズのからまでelement[j] - element[i]
の合計です。元のシリーズがある場合、累積シリーズはです。元のシリーズの位置までの合計はです。この問題では、0 から始まる合計のみに関心があるため、これは少しやり過ぎですが、他の問題ではより完全に役立ちます。i
j
[1, 2, 3, 4]
[0, 1, 3, 6, 10]
i
element[i] - element[0]
累積合計を作成するコードは次のとおりです。
def cumulative_sum(series):
s = [0]
for element in series:
s.append(element + s[-1])
return s
それを考えると、次のコードでピボット ポイントを見つけることができます。
def find_pivot(series):
cs = cumulative_sum(series)
total = cs[-1]
even_total = not (total & 1)
if even_total:
target = total // 2
for i, element in enumerate(cs[1:]):
if element == target:
return i + 1
return -1
系列の合計が奇数になることがわかっている場合は、系列を分割する必要がないことに注意してください。その場合、ピボット ポイントは存在しません。
find_pivot
または、次のように書くこともできます。
def find_pivot(series):
cs = cumulative_sum(series)
total = cs[-1]
even_total = not (total & 1)
if even_total:
target = total // 2
try:
return cs.index(target)
except ValueError:
return -1
return -1
ループが Python で明示的に行われるのではなく、標準ライブラリの C コードで行われるという利点があります。
コードを試す:
def test():
for i in range(1, 30):
test_values = range(i)
j = find_pivot(test_values)
if j >= 0:
print "{0} == {1}".format(test_values[:j], test_values[j:])
そして、次の出力が得られます。
[0] == []
[0, 1, 2] == [3]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] == [15, 16, 17, 18, 19, 20]