码迷,mamicode.com
首页 > 其他好文 > 详细

随手练——几个递归小题目

时间:2019-02-10 14:57:13      阅读:190      评论:0      收藏:0      [点我收藏+]

标签:php   pid   []   abc   clu   roc   base   swa   顺序   

递归最重要的两点:

1.base case(递归出口)。必须有某些基本情形,它无需递归就能解出。 

2.分解 或者 分类。分解成子问题,或者每层递归分叉,也就是一个N叉树模型。

 例题:

  • 打印一个字符串的所有子串

分解:按顺序每个字母是否打印,分解。

技术图片

 base case: 当 pos==length,分解到了最后一步

void process(char *s,int pos,int length,string res) {
    if (pos == length) {
        cout << res << endl;
        return;
    }
    process(s, pos + 1,length,res);
    process(s, pos + 1, length, res + s[pos]);
}
int main() {
    char str[] = "abc";
    process(str, 0, 3,"");
    return 0;
}
  • 打印一个字符串的全排列

void process(string s,int n) {
    if (n == s.length()) {
        cout << s << endl;
        return;
    }
    for (int i = n; i < s.length(); i++) {
        swap(s[i],s[n]);        
        process(s,n+1);
    }
}
  • 给定一个数组,数组中元素能否累加得到 指定值aim

要注意带返回值的递归函数写法:

bool recur(int *a, int n,int res,int aim,int length) {
    if (n == length || res == aim) {
        return res == aim;
    }
    return recur(a, n + 1, res + a[n], aim,length)|| recur(a, n + 1, res, aim,length);    
}
  • 不是所有题目都适合用递归

比如:HDU 2018:http://acm.hdu.edu.cn/showproblem.php?pid=2018

两种解法,虽然递归解法要短很多,但是时间上,填表要快很多,因为递归会重复计算已经算过的值:

#include <iostream>
using namespace std;
int a[55];
int f(int n) {
    if (n <= 4) return n;
    return f(n - 1) + f(n - 3);
}
int main() {
    int n;
    a[1] = 1; a[2] = 2; a[3] = 3; a[4] = 4;
    for (int i = 5; i < 55; i++) {
        a[i] = a[i - 1] + a[i - 3];
    }
    while (cin >> n) {
        if (n == 0)break;
        cout << a[n]<< endl;
    }
    return 0;
}

 

随手练——几个递归小题目

标签:php   pid   []   abc   clu   roc   base   swa   顺序   

原文地址:https://www.cnblogs.com/czc1999/p/10357290.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!