如何使用LINQ选择最小子序列?

时间:2014-04-09 13:01:37

标签: linq

如果我有一系列高尔夫结果:

 -3, +5, -3, 0, +1, +8, 0, +6, +2, -8, +5

我需要找到一个具有最小总和的三个相邻数字的序列。对于此示例,子序列将是:

 [-3, +5, -3]
 [+5, -3,  0]
 [-3,  0, +1]
 ... etc ...
 [+2, -8, +5]

最小序列为[-3, 0, +1],总和为-2。

3 个答案:

答案 0 :(得分:5)

您可以使用此LINQ查询:

int[] golfResult = { -3, +5, -3, 0, +1, +8, 0, +6, +2, -8, +5 };
var combinations = from i in Enumerable.Range(0, golfResult.Length - 2)
                   select new { 
                       i1 = golfResult[i], 
                       i2 = golfResult[i + 1], 
                       i3 = golfResult[i + 2], 
                   };
var min = combinations.OrderBy(x => x.i1 + x.i2 + x.i3).First();
int[] minGolfResult = { min.i1, min.i2, min.i3 }; // -3, 0, +1

当然,您需要检查数组中是否至少有三个结果。

答案 1 :(得分:2)

我不确定你为什么要用LINQ做这件事。我认为直接的迭代解决方案更容易理解:

int[] scores = new[] { -3, 5, -3, 0, 1, 8, 0, 6, 2, -8, 5 };

int minimumSubsequence = int.MaxValue;
int minimumSubsequenceIndex = -1;

for (int i = 0; i < scores.Length - 2; i++)
{
    int sum = scores[i] + scores[i + 1] + scores[i + 2];

    if (sum < minimumSubsequence)
    {
        minimumSubsequence = sum;
        minimumSubsequenceIndex = i;
    }
}

// minimumSubsequenceIndex is index of the first item in the minimum subsequence
// minimumSubsequence is the minimum subsequence's sum.

答案 2 :(得分:1)

如果你真的想在LINQ中这样做,你可以这样:

int length = 3;
var scores = new List<int>() { -3, +5, -3, 0, +1, +8, 0, +6, +2, -8, +5 };
var results =
    scores
    .Select((value, index) => new
    {
        Value = scores.Skip(index - length + 1).Take(length).Sum(),
        Index = index - length + 1
    })
    .Skip(length - 1)
    .OrderBy(x => x.Value)
    .First()
    .Index;

这将创建第二个列表,该列表汇总所有长度前面的元素,然后对其进行排序。