关于一类用简单迭代可以解答算法题的解法
2013-05-16 17:10
309 查看
有一类算法题,其实最简单的解法就是用简答迭代。但是,这不意味着这类算法题可以很容易被解答,关键在于对它的识别。一旦识别出,解答相对简单;但是一旦没有识别出,这类问题的解答不但麻烦,而且复杂度可能很高,达不到要求。举一个例子:
题目大意:一个字符串,不包含a, e, i, o, u的子字符串并满足一定长度要求则是我们想要的。题目给出若干字符串和长度要求,找出所有包含符合要求的子字符串的子字符串数量。比如:“quartz",长度要求:3. 则有如下子字符串满足要求:rtz, artz, uartz, quartz。一共四个。注意:因为rtz满足要求,artz即便包含了'a',但是只要它包含了一个满足要求的子字符串就满足我们的要求。
这是一道竞赛题。如果我们找到了一个满足要求的子字符串,并且该字符串左边有n个字符,右边有m个字符,则一共可以组成(n+1)*(m+1)个满足要求的字符串。但是如果对所有满足要求的子字符串这样计算并最后求和,则会有重复的情况。如果你想用排列组合的知识先求出所有的字符串在减去重复的,则不但很麻烦而且复杂度很高。
按照迭代的思路,先求出第一个满足要求的字符串并计算包含它的所有字符串数量,然后移动整个字符串开始的位置到这个子字符串的第一个字符后,再按照相同的思路寻找下一个满足要求的子字符串,不但复杂度很低(只有O(n * l)),而且程序很好些。比如我就可以一遍写对。代码如下:
对于所有的算法问题,特别是应该是比较简单的算法问题,思考时一定不要让迭代方法逃出自己的大脑,而且应该第一步就考虑一下是否可以用迭代解决该问题。
题目大意:一个字符串,不包含a, e, i, o, u的子字符串并满足一定长度要求则是我们想要的。题目给出若干字符串和长度要求,找出所有包含符合要求的子字符串的子字符串数量。比如:“quartz",长度要求:3. 则有如下子字符串满足要求:rtz, artz, uartz, quartz。一共四个。注意:因为rtz满足要求,artz即便包含了'a',但是只要它包含了一个满足要求的子字符串就满足我们的要求。
这是一道竞赛题。如果我们找到了一个满足要求的子字符串,并且该字符串左边有n个字符,右边有m个字符,则一共可以组成(n+1)*(m+1)个满足要求的字符串。但是如果对所有满足要求的子字符串这样计算并最后求和,则会有重复的情况。如果你想用排列组合的知识先求出所有的字符串在减去重复的,则不但很麻烦而且复杂度很高。
按照迭代的思路,先求出第一个满足要求的字符串并计算包含它的所有字符串数量,然后移动整个字符串开始的位置到这个子字符串的第一个字符后,再按照相同的思路寻找下一个满足要求的子字符串,不但复杂度很低(只有O(n * l)),而且程序很好些。比如我就可以一遍写对。代码如下:
const int fcn = 5; char fcs[fcn] = {'a', 'e', 'i', 'o', 'u'}; bool isOK(char c) { for (int i=0; i<fcn; i++) if (c == fcs[i]) return false; return true; } ////////////////////////////////////////////////////// int main(int argc, char* argv[]) { srand(time(0)); ifstream inf(argv[1]); string ln; inf >> ln; int number = atoi(ln.c_str()); for (int cases=0; cases<number; cases++) { string s; int l = 0; inf >> s >> l; vector<bool> v; v.resize(s.size()); int tl = 0; for (int i=s.size()-1; i>=0; i--) { if (isOK(s[i]) ) { tl++; } else { tl = 0; } if (tl == l){ v[i] = true; tl --; } else { v[i] = false; } } __int64 r = 0, start = 0; for (int i=0; i<s.size(); i++) { if (v[i]) { r += (i-start+1)*(s.size() - i - l + 1); start = i+1; } } // print result cout << "Case #" << (cases + 1) << ": " << r << endl; } return 0; }
对于所有的算法问题,特别是应该是比较简单的算法问题,思考时一定不要让迭代方法逃出自己的大脑,而且应该第一步就考虑一下是否可以用迭代解决该问题。
相关文章推荐
- 以下是关于二叉树操作的11个简单算法
- 关于印象笔记的扫描宝——简单的图像背景去除(去底色)算法小结
- 关于ie事件多投内存泄漏的一种简单解法
- 关于微信红包简单算法 PHP Edition
- 简单常识——关于 STL 算法
- bzoj1007: [HNOI2008]水平可见直线 关于一类半半平面交题目的解法研究
- 一个简单的算法关于list
- 【算法学习笔记】17.暴力求解法05 隐式图搜索1 迭代加深搜索 埃及分数
- 简单常识——关于 STL 算法
- 关于简单数据压缩的算法
- 简单算法--迭代/递归
- 【算法学习笔记】17.暴力求解法05 隐式图搜索1 迭代加深搜索 埃及分数
- 关于socket用winform实现简单通信 大牛可绕道 初学者可以看看 我做的时候把客户端窗口隐藏了 大家可以自己改一下
- 关于最大公约数的三种解法之二(连续整数检测算法)
- 关于算法中递归与迭代的小感想
- 简单常识——关于 STL 算法
- 关于算法导论15.4的步骤2中为什么可以通过求两者的最大值来合并定理15.1
- 关于开方的迭代算法
- 关于视频剪辑算法的简单实现
- 写的一个简单的工具类,可以做对象类型的判断和迭代出一个对象所有属性的值