我正在尝试将一个链表分成两个具有相等总和的子列表。这些子列表不需要由连续元素组成。
我有一个链接列表
Eg.1
LinkedList={1,7,5,5,4}
should be divided into
LinkedList1={1,5,5}
LinkedList2={7,4}
两者都具有与11相同的元素总和。
Eg.2
LinkedList={42,2,3,2,2,2,5,20,2,20}
This should be divided into two list of equal sum i.e 50.
LinkedList1={42,3,5}
LinkedList2={2,2,2,2,20,2,20}
有人可以提供一些伪代码来解决这个问题吗?
这是我到目前为止所想的:
对链表的元素求和并除以2.
现在直到你的linkedlist1的总和小于linkedlist / 2的总和,继续将元素推送到linkedlist1。
如果不相等且小于linkedlist sum / 2移动到下一个元素,则当前元素可以推送到linkedlist2。
但这只有在元素按特定顺序排列时才有效。
答案 0 :(得分:1)
有几种方法可以解决这个问题,但我只会提到下面最常见的2(有关这两种方法或其他方法的详细信息,请参阅Wikipedia。)
这可以通过dynamic programming方法解决,该方法基本上归结为每个元素和值,包括或排除该元素,并查找是否存在与相应值相加的子集。更具体地说,我们有以下递归关系:
如果p(i, j)
的子集总和为True
和{ x1, ..., xj }
,则如果
i
为False
。p(i, j)
为True
或p(i, j − 1)
为True
,则
p(i − xj, j − 1)
为True
p(i, j)
是False
否则
然后p(N/2, n)
告诉我们是否存在子集。
运行时间为O(Nn)
,其中n
是输入集中元素的数量,N
是输入集中元素的总和。
“近似”贪婪方法(不一定找到等和分区)非常直接 - 它只涉及将每个元素放入具有最小和的集合中。这是伪代码:
INPUT: A list of integers S
OUTPUT: An attempt at a partition of S into two sets of equal sum
1 function find_partition( S ):
2 A ← {}
3 B ← {}
4 sort S in descending order
5 for i in S:
6 if sum(A) <= sum(B)
7 add element i to set A
8 else
9 add element i to set B
10 return {A, B}
运行时间为O(n log n)
。