诀窍是找出一种方法来对可能的解决方案进行分类,并为每个解决方案提出一个线性时间常数空间解决方案。
考虑三个范围X = (0,2/3), Y = [2/3,1], Z = (1,2)。最多一个值可以来自Z(如果两个值来自Z,那么总和将超过1+1=2)。同样,至少一个值必须来自X。假设有 3 个值 a <= b <= c ,所以 1 <= a+b+c <= 2 。然后,考虑哪些可能的解决方案类别是可行的:
A) `a \in X, b \in X, C \in X`
B) `a \in X, b \in X, C \in Y`
C) `a \in X, b \in X, C \in Z`
D) `a \in X, b \in Y, C \in Y`
E) `a \in X, b \in Y, C \in Z`
那么我们如何测试每个案例呢?
案例 A 非常容易测试:总和保证小于 2,因此我们只需要测试最大总和(X 中最大的 3 个元素)是否超过 1。
案例 C 非常容易测试:因为保证总和大于 1,我们只需要检查总和是否低于 2。因此,为了做到这一点,我们只需要测试最小的 2 个值X和Z中的最小值
情况 D 和 E 与 C 类似(由于总和必须至少为 4/3 > 1,因此请在每个类别中选择可能的最小值)。
案例 B 是唯一棘手的案例。 0 < a+b < 4/3 和 2/3 <= c <= 1。为了处理案例 B,我们考虑这些区间:X1 = (0, 1/2), X2 = [1/2 2/3), Y = [2/3, 1]。
这导致以下三种有效情况:
B1。 X1 中的 a,X2 中的 b,Y 中的 c
B2。 X1中的a,X1中的b,Y中的c
B3。 X2中的a,X2中的b,Y中的c
案例 B1 和 B3 :三个数字的总和总是大于 1,所以我们取最小值并检查它是否小于 2。
案例B2:三个数字的和总是小于2,所以我们取最大和并检查是否大于1。
总而言之,测试是:
-
|X| >= 3 和 Xmax(1) + Xmax(2) + Xmax(3) >= 1
-
|X| >= 2、|Z| >= 1 和 Xmin(1)+Xmin(2)+Zmin(1) <= 2
-
|X| >= 1、|Y| >= 2 和 Xmin(1)+Ymin(1)+Ymin(2) <= 2
-
|X| >= 1、|Y| >= 1、|Z| >= 1 和 Xmin(1)+Ymin(1)+Zmin(1) <= 2
-
|X| >= 2、|Y| >= 1 和 Xmax(1) + Xmax(2) + Ymin(1) < 2
-
|X| >= 2、|Y| >= 1 和 Xmin(1) + Xmin(2) + Ymax(1) > 1)
每次测试都可以在线性时间和常数空间中进行(只需找到Xmax(1), Xmax(2), Xmax(3), Xmin(1), Xmin(2), Ymin(1), Ymin(2), Ymax(1), Zmin(1),即使数据没有排序也可以一次性找到)