假设你的数字都是非负数,你可以使用更有效的算法。您只需通过列表运行两个指针ptrA
和ptrB
,并保持包含元素的总和。
如果总和不是你需要什么,你做两件事之一。首先,如果您的当前总和小于所需的总和,则通过推进ptrB
使下一个元素进入阵列。
如果您当前的总和为,则您需要的数量多于,您可以通过前进ptrA
取出范围内的第一个元素。这两种操作当然都应该调整当前的范围总和。这里有一个边缘案例,如果目前只有一个项目在范围内,您不想这样做。
而且不言而喻,如果当前范围总和等于您所需,您只需删除该范围并退出。
在伪代码而言,这将是这样的:
def delExact(list, desiredSum):
# Check non-empty and start range.
if list is empty:
return
ptrA = list.first
ptrB = ptrA
rangeSum = ptrA.value
# Continue until match found
while rangeSum is not equal to desiredSum:
# Select add-another or remove-first.
if ptrA == ptrB, or rangeSum < desiredSum:
# Need to bring another in, returning if list exhausted.
ptrB = ptrB.next
if ptrB == null:
return
rangeSum = rangeSum + ptrB.value
else:
# Need to remove one.
rangeSum = rangeSum - ptrA.value
ptrA = ptrA.next
# If we exit the loop, we've found a sum match.
# Hence we need to delete ptrA through ptrB inclusive.
但是,如果负数被允许,因为你真的不知道两个指针的方式打破了什么样的影响以后的元素可能有。
在这种情况下,你基本上做一个穷举搜索的所有可能性,这基本上可以归结为:
for each element in list:
for each possible segment from that element on:
check and act on summed data
这实际上更多的英语表示,对于这样的野兽伪代码将沿着线:
def delExact(list, desiredSum):
# For each list element.
ptrA = list.first
while ptrA is not null:
# For each possible segment starting at that element.
segmentSum = 0
ptrB = ptrA
while ptrB is not null:
add ptrB.value to segmentSum
# Delete segment if sum matches, then return.
if segmentSum is equal to desiredSum:
# Here we delete from ptrA through ptrB inclusive.
return
# Otherwise, keep adding elements to segment.
ptrB = ptrB.next
# No matching segment, move on to next element.
ptrA = ptrA.next
# No matching segment at any element, just return.
采用这些算法要么将解决你唯一的问题有关删除两个元素。
在列表开始时删除的问题是简单地识别该事实(ptrA == list.first
),并确保在此情况下调整指针first
。这是链表处理中的标准边缘情况,并且可以实现为如下类似:
def deleteRangeInclusive(list, ptrA, ptrB):
# Adjust list to remove ptrA/ptrB segment,
# allowing for possibility ptrA may be the head.
if ptrA == list.first:
list.first = ptrB.next
else:
beforeA = list.first
while beforeA.next != ptrA:
beforeA = beforeA.next
beforeA.next = ptrB.next
# Now we can safely remove the ptrA-ptrB segment.
while ptrA != ptrB:
tempA = ptrA
ptrA = ptrA.next
delete element tempA
delete element ptrB
一个普遍技巧是不要修改输入参数,如'LISTA * p',而是使用其他指针在列表中移动。这可能会提示你解决你的第一个问题。 – Jerry