//https://en.wikipedia.org/wiki/Patience_sorting public static int[] LASIndices(IReadOnlyList <int> sequence) { ; if (sequence.Count == 0) { return(new int[0]); } var pileTops = new List <LCANode> { new LCANode(0, null) }; for (int i = 1; i < sequence.Count; i++) { int v = sequence[i]; //binary search for the first pileTop > v int a = 0; int b = pileTops.Count; while (a != b) { int c = (a + b) / 2; if (sequence[pileTops[c].value] > v) { b = c; } else { a = c + 1; } } if (a < pileTops.Count) { pileTops[a] = new LCANode(i, a > 0 ? pileTops[a - 1] : null); } else { pileTops.Add(new LCANode(i, pileTops[a - 1])); } } //follow pointers back through path var las = new int[pileTops.Count]; int j = pileTops.Count - 1; for (var node = pileTops[j]; node != null; node = node.prev) { las[j--] = node.value; } return(las); }
public LCANode(int value, LCANode prev) { this.value = value; this.prev = prev; }