最长排序子序列的长度

时间:2014-03-04 11:13:29

标签: c# arrays algorithm subsequence

我的未排序数组是

string[] a = new string[] { "10", "22", "9", "33", "21", "50", "41", "60", "80" };

在此数组中,10,22,33,50,60,80按升序排列, 所以输出必须是6

一般来说,我想要一个升序列表的最长可能长度,该列表由数组元素组成,并以第一个元素开头。

我试过这个:

string[] a = new string[] { "10", "22", "9", "33", "21", "50", "41", "60", "80" };
List<int> res = new List<int>();
int arrLength = a.Length;
int i = 0;
int prev;
while (i < arrLength)
{
    if (i < arrLength)
    {
        res.Add(Convert.ToInt32(a[i]));
        prev = Convert.ToInt32(a[i]);
        while (Convert.ToInt32(a[++i]) < prev) { }
    }
}

int asdf = res.Count;

但没有成功。

5 个答案:

答案 0 :(得分:4)

这称为Longest Ascending Subsequence问题。您可以使用文章中描述的简单动态编程算法找到它。

如果您需要的是最长子序列的长度,您可以这样做:

// length[i] is the length of subsequence ending at position i
var length = new int[a.Length];
for (var i = 0 ; i != length.Length ; i++) {
    // In the worst case a number ends a subsequence of length 1
    length[i] = 1;
    var ai = Convert.ToInt32(a[i]);
    // Go backward on the items that we've seen before
    for (var j = i-1 ; j >= 0 ; j--) {
        var aj = Convert.ToInt32(a[i]);
        // If number at i is greater than the number at j, use the length of j's longest subsequence
        // to calculate the length of the sequence for element at i.
        if (aj > ai && length[j]+1 > length[i]) {
            length[i] = length[j]+1;
        }
    }
}
var res = length.Max();

您的算法不正确,因为它使用“贪婪策略”,即它认为任何数字比先前找到的数字大一部分。

答案 1 :(得分:0)

即使你是经理让它正确计数,你也可能会遇到问题。

如果要发现多个有序的值集,您想要发现两者还是仅发现第一个或从最小数字开始的那个等等怎么办?

首先需要做的是获取数组并按照您需要的顺序创建它的副本。然后,您需要对循环的无序数组执行检查,并将值与有序数组进行比较,并在排序停止时断开循环。但是您仍然需要考虑从中获取数据的其他方面,并将其包含在您的代码中。

答案 2 :(得分:0)

作业?这是可以使用dynamic programming解决的问题的教科书示例。数组longest将保持以相同位置上的元素结尾的最长的增加子系列。

public int LongestIncreasingSubseries(int[] input)
{
  int[] longest = new int[input.Length];
  int result = 1;
  for(int i = 0; i<input.Length; ++i) 
  {
    longest[i] = 1;
    for(j=0; j<i; ++j) if (input[j]<input[i] && longest[j]+1>longest[i]) longest[i] = longest[j]+1;
    if(longest[j]>result) result = longest[i];
  }
  return result;
}

答案 3 :(得分:0)

string[] arr = new string[] { "10", "22", "9", "33", "21", "50", "41", "60", "80" };
int biggest = int.MinValue;
int current = 0;

int count = (from str in arr
             where int.TryParse(str, out current)
             let number = current
             where number > biggest
             select biggest = number).Count();

此LINQ查询获取每个字符串,并尝试将其转换为数字。如果成功,则检查该数字是否大于最后一个最大数字。如果确实如此 - 将该数字存储为新的最大数字 - 并将其返回。

Count方法只计算已返回的项目数(但您可以将它们存储在数组中,或者在foreach循环中迭代它们,或者任何东西)。

答案 4 :(得分:0)

这是我的答案。

很容易理解你

string[] a = new string[] { "10", "22", "9", "33", "21", "50", "41", "60", "80" };
        List<int> res = new List<int>();
        int arrLength = a.Length;
        int i = 0;
        for (i = 0; i < arrLength; i++)
        {
            if (i < arrLength)
            {
                if (res.Count != 0)
                {
                    if (Convert.ToInt32(a[i]) > res[res.Count - 1])
                    {
                        res.Add(Convert.ToInt32(a[i]));
                    }
                }
                else
                {
                    res.Add(Convert.ToInt32(a[i]));
                }
            }
        }

        int asdf = res.Count;

输出为6

请参阅此screen short

您可以下载我的代码here