存在多少个连续的数组子阵列,使得它们不包含数组的某些位置对?例如。如果array = {11,22,33,45}并且如果我们不想包括说位置编号(1,3)和(2,4)那么存在的连续子阵列的数量是7,如下{{11 },{22},{33},{44},{11,22},{22,33},{33,45}}
我尝试解决问题:
如果存在两对{...,a1,...,a2,..,b1,..,b2},其中n是元素的数量,(...)表示有元素在这些职位之间。
第一种情况:我们不能包括{a1,b1}和{a2,b2}然后我们必须计算可能的组合数,即n *(n + 1)/ 2 - 否。可能的组合包括{a2,b1},涵盖所有可能的
案例2.如果我们不能包含对{a1,b2}和{a2,b1},那么我们只需减去包含{a2,b1}的可能性的数量,其中包含所有可能的案例。
第3种情况:如果我们不能包含对{a1,a2}和{b1,b2}那么我们必须单独减去可能的子阵列,包括这些位置
我面临的问题是,即使在制定案例后,我也无法推导出一个公式,并将这些案例扩展到2对以上,以计算可能的解决方案的数量。所以,我需要帮助。
来源:这是一个面试问题,问我的朋友,他无法回答。
答案 0 :(得分:0)
好的,让我们再看一下阵列{11,22,33,44}。
让我们假设您正在尝试查找以11开头的所有子阵列(index = 1)。现在你只需要查看索引< = a和b是最小的限制(a,b),因为如果你有例如(2,3)这自动暗示(1,4)或(2,4)。
要查找最小b,请使用以下代码(我使用C#):
public static int findRestrictingIndex(int currentIndex, List<Tuple<int, int>> restrictions)
{
int result = int.MaxValue;
foreach (var pair in restrictions)
{
if (currentIndex <= pair.Item1)
{
if (pair.Item2 < result)
result = pair.Item2;
}
}
return result;
}
如果您运行此代码,您将收到3(来自(1,3))的结果。以11开头的数组的数量则为3-1 = 2,因为您可以将数字添加到11直到排除索引3。
为每个索引执行此操作,您将完成:
int arrayLength = 4;
//excluded positions, zero-based
List<Tuple<int, int>> restrictions = new List<Tuple<int, int>>();
restrictions.Add(new Tuple<int, int>(0, 2));
restrictions.Add(new Tuple<int, int>(1, 3));
restrictions.Add(new Tuple<int, int>(4, 4)); //dummy element when there is no restriction
int numOfSubarrays = 0;
for (int currentIndex = 0; currentIndex < arrayLength; currentIndex++)
{
numOfSubarrays += findRestrictingIndex(currentIndex, restrictions) - currentIndex;
}
Console.WriteLine(numOfSubarrays);