假設你的數字都是非負數,你可以使用更有效的算法。您只需通過列表運行兩個指針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