[经典] 最X(长 | 大和 | 大积)Y(子序列 | 子字符串)
Posted 小尾巴君
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[经典] 最X(长 | 大和 | 大积)Y(子序列 | 子字符串)相关的知识,希望对你有一定的参考价值。
Note: 子序列,可以不连续;子字符串,必须连续。
以下题目按在我看看来的难度从易到难排列:
最大和子序列(Maximum sum subsequence)
这道题纯属娱乐...应该不会有人出这种题吧。方案是遇到正数就放入序列。
vector<int> msseq(vector<int> &num) { vector<int> result; for(int i : num) if(i > 0) result.push_back(i); return result; }
最长递增子字符串(Longest increasing substring)
暴力方案TC为O(n^2)。更好的方案为,贪心法,设i从0到n遍历,用gmax代表全局最长长度,len代表当前递增substring的长度。遇到递增,则len++;遇到非递增,则更新gmax,并重置len为1。TC = O(n),SC = O(1)
string lis(string str) { if(str.empty()) return str; string recstr = "", curstr = ""; curstr += str[0]; int gmax = INT_MIN, len = 1; for(int i = 1; i < str.length(); i++) { if(str[i] > str[i - 1]) { len++; curstr += str[i]; } else { //假设只需要返回一个最长的,如果要返回全部则用vector存 if(gmax < len) { gmax = len; recstr = curstr; } curstr = ""; len = 1; } } return recstr; }
最长递增子序列(Longest increasing subsequence)
暴力方案TC为O(2^n)。如果用贪心法,分析知道根据第i个包含的信息,无法覆盖前i个数的情况,故第i+1个数的决策没法做;更好的方案为,动态规划,用opt[i]记录到i为止最长的且包含 i上字符的最长递增subsequence。
vector<int> miseq(vector<int> &num) { vector<int> result; if(num.empty()) return num; vector<int> opt(num.size(), 1), record(num.size(), -1); for(int i = 0; i < num.size(); i++) { for(int j = 0; j < i; j++) { if(num[i] > num[j] && opt[j] + 1 > opt[i]) { opt[i] = opt[j] + 1; record[i] = j; } } } int last = -1, gmax = 0; for(int i = 0; i < num.size(); i++) { if(opt[i] > gmax) { gmax = opt[i]; last = i; } } while(last >= 0) { result.push_back(num[last]); last = record[last]; } reverse(result.begin(), result.end()); return result; }
最长无重复字符串
最长匹配子字符串
编辑距离
最大和子序列
最大乘积子序列
最大乘积子字符串
以上是关于[经典] 最X(长 | 大和 | 大积)Y(子序列 | 子字符串)的主要内容,如果未能解决你的问题,请参考以下文章