Tôi có danh sách các số (ví dụ: [-1, 1, -4, 5]
) và tôi phải xóa số khỏi danh sách mà không thay đổi tổng số của danh sách. Tôi muốn xóa các số có giá trị tuyệt đối lớn nhất có thể, mà không thay đổi tổng số, trong ví dụ xóa [-1, -4, 5]
sẽ để lại [1]
để tổng không thay đổi.xóa số khỏi danh sách mà không thay đổi tổng số
Tôi đã viết cách tiếp cận ngây thơ, tìm tất cả các kết hợp có thể không thay đổi tổng số và xem kết hợp nào loại bỏ giá trị tuyệt đối lớn nhất. Nhưng điều đó rất chậm vì danh sách thực tế sẽ lớn hơn rất nhiều.
Đây là mã kết hợp của tôi:
from itertools import chain, combinations
def remove(items):
all_comb = chain.from_iterable(combinations(items, n+1)
for n in xrange(len(items)))
biggest = None
biggest_sum = 0
for comb in all_comb:
if sum(comb) != 0:
continue # this comb would change total, skip
abs_sum = sum(abs(item) for item in comb)
if abs_sum > biggest_sum:
biggest = comb
biggest_sum = abs_sum
return biggest
print remove([-1, 1, -4, 5])
Nó corectly in (-1, -4, 5)
. Tuy nhiên tôi đang tìm kiếm một số giải pháp thông minh, hiệu quả hơn so với lặp trên tất cả các kết hợp mục có thể.
Bất kỳ ý tưởng nào?
Trong trường hợp này, đó là một chiến thắng nếu chúng ta quan sát rằng tổng là một mục trong danh sách này. Nếu chúng ta có 'sum (items)' và 'abs_sum (items)' thì nó có khả năng hiệu quả hơn khi cố gắng cộng lại với tổng bằng cách sử dụng các phần tử 1, 2, 3, etc từ danh sách, bắt đầu từ trường hợp danh sách trống thay vì danh sách đầy đủ (?) – u0b34a0f6ae
Có lẽ bạn nên lưu 'tiny_abs_sum' thay vì' greater_sum'. Xem xét: '[1, -1,100, -100]'. – jfs
@ J.F. Sebastian: Nếu đầu vào là '[1, -1,100, -100]' nó sẽ loại bỏ mọi thứ ('abs_sum' của' 202') giữ tổng '0'. – nosklo