划分为增加的子序列


16

规格

这个挑战很容易说明:您的输入是一个非负整数的非空数组,您的任务是将其划分为尽可能少的递增子序列。更正式地讲,如果输入数组是A,则输出是一个数组数组B,使得:

  • 每个阵列B形成A不相交(不一定是连续的)子序列的分区。在归纳法上,这意味着要么B是包含的单例数组,要么是的A第一个元素B是的子序列,A其余部分形成的分区,A并且删除了该子序列。
  • B(不一定严格)增加每个数组。
  • 中的数组数量B最少。

输入和输出都可以采用您语言的本机数组格式。请注意,可能有几个正确的输出。

考虑输入数组A = [1,2,1,2,5,4,7,1]。一种可能的输出是B = [[1],[1,2,4,7],[1,2,5]]。从此图可以明显看出分区条件:

A    1 2 1 2 5 4 7 1
B[0]               1
B[1] 1 2       4 7
B[2]     1 2 5

同样,每个数组都在B增加。最后,A由于不能分为两个递增的子序列,因此的长度B也很短。因此,这是有效的输出。

规则和计分

您可以编写函数或完整程序。最低字节数获胜,并且不允许出现标准漏洞。没有时间限制,但是您应该在提交所有测试用例之前对解决方案进行评估。

测试用例

仅显示一个可能的输出,但可能有多个有效选项。特别地,结果中数组的顺序无关紧要(但每个单独的数组应按递增顺序排列)。

[0] -> [[0]]
[3,5,8] -> [[3,5,8]]
[2,2,2,2] -> [[2,2,2,2]]
[1154,1012,976,845] -> [[845],[976],[1012],[1154]]
[6,32,1,2,34,8] -> [[1,2,8],[6,32,34]]
[1,12,1,12,1,13] -> [[1,1,1,13],[12,12]]
[6,4,6,13,18,0,3] -> [[0,3],[4,6,13,18],[6]]
[1,2,3,2,3,4,7,1] -> [[1,1],[2,2,3,4,7],[3]]
[0,9,2,7,4,5,6,3,8] -> [[0,2,3,8],[4,5,6],[7],[9]]
[7,1,17,15,17,2,15,1,6] -> [[1,1,6],[2,15],[7,15,17],[17]]
[4,12,2,10,15,2,2,19,16,12] -> [[2,2,2,12],[4,10,15,16],[12,19]]
[10,13,9,2,11,1,10,17,19,1] -> [[1,1],[2,10,17,19],[9,11],[10,13]]
[3,7,3,8,14,16,19,15,16,2] -> [[2],[3,3,8,14,15,16],[7,16,19]]
[15,5,13,13,15,9,4,2,2,17] -> [[2,2,17],[4],[5,9],[13,13,15],[15]]

3
规则似乎允许类似的解决方案[0,5,2,0] -> [[0,5],[0,2]](例如,回收第一个零而不是每个都使用一次)。那是故意的吗?
feersum

@feersum并不是故意的,很好。我已重写的条件B,希望现在可以更清楚了。
Zgarb 2015年

Answers:


3

Haskell,54个字节

n#[]=[[n]]
n#(l:c)|[n]<=l=(n:l):c|1<2=l:n#c
foldr(#)[]

用法示例:foldr(#)[] [4,12,2,10,15,2,2,19,16,12]->[[2,2,2,12],[4,10,15,16],[12,19]]

工作原理:从右端开始浏览输入列表。通过将当前元素放在n第一个子列表(小于或等于的开头)的位置来构建(列表的)输出列表。如果不存在,请在输出列表的末尾创建一个新的单例列表。lnln


1

Pyth,20个字节

fTu&ahfSI+THGHGQm[)Q

在线尝试:演示测试套件

贪婪的方法。我创建len(input)空列表。然后,我遍历一个中的每个数字,然后input选择第一个列表,该列表在附加数字之后仍然排序。

说明:

fTu&ahfSI+THGHGQm[)Q   implicit: Q = input list
                m[)Q   create a list of empty lists and assign to G
  u            Q       iterate over all numbers H in input:
      f     G             filter for lists T in G, which satisfy:
         +TH                 create a new list out of T and H
       SI                    and check if it is sorted
     h                    take the first such list T
    a        H            and append H
   &          G           logical and with G (so that u doesn't overwrite G)
fT                     remove all empty lists

@ThomasKwa现在已经测试了很多其他测试用例。找不到一个,给出了错误的结果。我很确定,贪婪总是返回正确的结果。
雅库布2015年

@ThomasKwa哦,那个反例是一个不同的贪婪策略(找到最长的递增子序列,将其删除并递归)。我似乎也找不到该提交失败的测试用例……
Zgarb 2015年

好吧,我认为回答者要证明自己的想法是行得通的。如果证明有效,我将投票。
lirtosiast 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.