O(n)時間の複雑さを達成するためにスタックを使用できます。文字列内の文字を繰り返し、各文字のチェックで、スタックの先頭に同じ文字が含まれているかどうかを確認します。場合は、スタックからキャラクターをポップし、次のアイテムに移動します。それ以外の場合は、文字をスタックにプッシュします。私は正規表現の速度を測定し、100
の入力長とベースのソリューションを積層するテストのカップルを走った議論に基づいて
s = 'aaabccddd'
stack = []
for c in s:
if stack and stack[-1] == c:
stack.pop()
else:
stack.append(c)
print ''.join(stack) if stack else 'Empty String' # abd
更新:スタック内に残っているものは何でも結果です。テストでは、Windows 8上のPython 2.7上で実行されました:ベンチマークに使用
All same
Regex: 0.0563033799756
Stack: 0.267807865445
Nothing to remove
Regex: 0.075074750044
Stack: 0.183467329017
Worst case
Regex: 1.9983200193
Stack: 0.196362265609
Alphabet
Regex: 0.0759905517997
Stack: 0.182778728207
コード:
import re
import timeit
def reduce_regexp(text):
even = re.compile(r'(?:([a-z])\1)+')
prev = len(text) + 1
while len(text) < prev:
prev = len(text)
text = even.sub(r'', text)
return text
def reduce_stack(s):
stack = []
for c in s:
if stack and stack[-1] == c:
stack.pop()
else:
stack.append(c)
return ''.join(stack)
CASES = [
['All same', 'a' * 100],
['Nothing to remove', 'ab' * 50],
['Worst case', 'ab' * 25 + 'ba' * 25],
['Alphabet', ''.join([chr(ord('a') + i) for i in range(25)] * 4)]
]
for name, case in CASES:
print(name)
res = timeit.timeit('reduce_regexp(case)',
setup='from __main__ import reduce_regexp, case; import re',
number=10000)
print('Regex: {}'.format(res))
res = timeit.timeit('reduce_stack(case)',
setup='from __main__ import reduce_stack, case',
number=10000)
print('Stack: {}'.format(res))
なぜ 'aab'を?これは 'aa'は入力サンプルの隣接するペアです。 –
あなたはHackerrankの問題について非常にうまく説明していません。サンプルは「aabcc」(2回「c」、3ではない)であり、それらは一連の** ** 1つの操作**について話している。 –
aabは1つの操作であるccを削除しているため、別の操作ではaaを削除してbを作成します。私は問題を正しく説明できなかったので、リンクが1つだけ提供されていることも修正しました。 –