问题:给定一个长度为N的数组,找出一个最长的单调自增子序列(不一定连续,但是顺序不能乱)。例如:给定一个长度为6的数组A{5, 6, 7, 1, 2, 8},则其最长的单调递增子序列为{5,6,7,8},长度为4.
分析:这里给出一种近乎求 所有的子单调序列的做法
这里的序列其实可以表示为一颗树来存储 如下图
故设计如下数据结构
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 { public class Leaf { public int key = 0; public List<Leaf> leafs = new List<Leaf>(); public Stack<int> stack = new Stack<int>(); private void OutTree(Leaf leaf) { if (leaf.leafs.Count <= 0) { Stack<int> sk = new Stack<int>(); foreach (var item in stack) { sk.Push(item); } foreach (var item in sk) { Console.Write(item + " "); } Console.WriteLine(); } foreach (Leaf item in leaf.leafs) { stack.Push(item.key); OutTree(item); stack.Pop(); } } public void OutTree() { OutTree(this); } public void OutTree(List<Leaf> list) { foreach (var item in list) { OutTree(item); } } } }
这里有个输出树的算法 使用的是dfs回溯法,使用一个栈来保存父节点序列以方便输出
具体算法如下。 获取每个序列的开头 这些序列都是以逆序形式存在的发现了这个特点 可以求出每个的开头然后递归求出每个子序列的子序列的开头。。。构造树
代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Collections; namespace ConsoleApplication1 { class Program { //森林 static Dictionary<int, List<int>> dicNums = new Dictionary<int, List<int>>(); static void Main(string[] args) { List<int> nums = new List<int>() { 4,7,5,2,3,4,1,5,100,99,2,5,6,7,9,13,17}; Leaf tree = GetTree(nums); for (int i = 0; i < tree.leafs.Count; i++) { dicNums.Add(tree.leafs[i].key, new List<int>()); } tree.OutTree(); Console.Read(); } static void OutPutTree(Leaf tree) { for (int i = 0; i < tree.leafs.Count; i++) { Console.Write(tree.leafs[i].key + " "); OutPutTree(tree.leafs[i]); } } //去掉最少的为单增就是单增 static Leaf GetTree(List<int> nums) { Leaf tree = new Leaf(); CreateTree(nums, tree); return tree; } static void CreateTree(List<int> nums, Leaf tree) { //leaf的简单集 Dictionary<int, List<int>> dic = new Dictionary<int, List<int>>(); for (int i = 0; i < nums.Count; i++) { Leaf leaf = CreateLeaf(nums, tree, dic, i); if (leaf != null) { tree.leafs.Add(leaf); } } if (tree.leafs.Count <= 0) { return; } foreach (var item in tree.leafs) { CreateTree(dic[item.key], item); } } private static Leaf CreateLeaf(List<int> nums, Leaf tree, Dictionary<int, List<int>> dic, int i) { bool flag = false; //key代表第一个数字 foreach (Leaf item in tree.leafs) { if (nums[i] > item.key) { dic[item.key].Add(nums[i]); //不存在新节点 flag = true; } } if (flag) { return null; } if (!dic.ContainsKey(nums[i])) { //不存在num Leaf leaf = new Leaf(); leaf.key = nums[i]; dic.Add(nums[i], new List<int>()); return leaf; } return null; } } }
输出结果: