直觉:
如果 sequence[i] > sequence[i+1]
,则路径已在左子树中搜索,序列中的下一个元素必须小于等于sequence[i]
否则,路径包括右子树的元素,序列中的下一个元素必须大于等于sequence[i]
我们可以使用上述逻辑编写暴力解决方案,其时间复杂度为O(n^2)
def any_element_greater(sequence, val):
for e in sequence:
if e > val:
return True
return False
def any_element_lesser(sequence, val):
for e in sequence:
if e < val:
return True
return False
def is_valid_seq(sequence):
if len(sequence) < 2:
return True
prev = sequence[0]
for idx, val in enumerate(sequence):
if prev > val:
if any_element_greater(sequence[idx:], prev):
return False
elif prev < val:
if any_element_lesser(sequence[idx:], prev):
return False
prev = val
return True
优化:
我们可以使用max
和min
变量来传递有效范围 - 记忆化。
def valid_sequence(sequence, i=0, m_min=1, m_max=1000):
'''
Checks if the Sequence is a correct path in BST
Parameters:
sequence: path to the data in the BST
i: current data we are validating in the path
m_min: data should be more than m_min
m_max: data should be less than m_max
Returns:
Boolean: If the sequence is a valid path in BST
'''
if len(sequence) == 0:
return True
data = sequence[i]
if not (m_min <= data <= m_max):
return False
if i == len(sequence) - 1:
return True
'''
Adjust min, max for the next data elements
depends on the next element in the sequence
'''
next = sequence[i+1]
if next > data:
m_min = max(m_min, data)
else:
m_max = min(m_max, data)
return valid_sequence(sequence, i+1, m_min, m_max)
测试:
options = {
'a': [2, 252, 401, 398, 330, 344, 397, 363],
'b': [924, 220, 911, 244, 898, 258, 362, 363],
'c': [925, 202, 911, 240, 912, 245, 363],
'd': [2, 399, 387, 219, 266, 382, 381, 278, 363],
'e': [935, 278, 347, 621, 299, 292, 358, 363]
}
for option in options:
print(f'{valid_sequence(options[option])} \t - {option}. {options[option]}')
结果:
True - a. [2, 252, 401, 398, 330, 344, 397, 363]
True - b. [924, 220, 911, 244, 898, 258, 362, 363]
False - c. [925, 202, 911, 240, 912, 245, 363]
True - d. [2, 399, 387, 219, 266, 382, 381, 278, 363]
False - e. [935, 278, 347, 621, 299, 292, 358, 363]
推理:
在选项c中,当我们进入240的左子树时,912大于911,因此它是无效的。
在选项e中,我们从347向右走,但在序列中遇到299和292,因此它是无效的。