算法总结(7)--leetcode上的递归,BFS,DFS思考

recursion
n. 递推; 递归,递归式;

下面的题目,也不是很难,不过需要注意递归调用的条件,如何递归
还有就是题意的理解

另外设计到重复结果的处理,如果序列有序的,可以在遍历的时候就处理,减少DFS数,还有就是直接用set去存储结果,保证不重复


38. Count and Say

题目地址

https://leetcode.com/problems/count-and-say/

题目意思和参考

http://blog.csdn.net/fly_yr/article/details/48000713

递归ac代码

class Solution {
public:
    string countAndSay(int n) {
        string rs;
        if (n <= 0)
            return rs;
        if (n == 1)
            return "1";
        string ans = countAndSay(n - 1); //递归
        int len = ans.size();
        int cnt = 1;

        for (int i = 0; i < len; i++)
        {
            if (i == len - 1)
            {
                rs += to_string(cnt);
                rs += ans[i];

                break;
            }
            if(ans[i] == ans[i+1])
            {
                cnt++;
            }
            else{
                rs += to_string(cnt);
                rs += ans[i];

                cnt = 1;
            }
        }

        return rs;
    }
};

22. Generate Parentheses

题目地址

https://leetcode.com/problems/generate-parentheses/

题目描述

Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.

For example, given n = 3, a solution set is:

[
  "((()))",
  "(()())",
  "(())()",
  "()(())",
  "()()()"
]

求解

这题采用的是dfs 回溯的方法,主要是如何构建递归函数

ac代码如下

class Solution {
public:
    vector<string> ans;

    /*
        left代表左括号的数目 <= n
        depth代表总共的数目  <= 2*n
    */
    void dfs(string s, int left,int depth,int n)
    {
        if (depth >= 2 * n)
        {
            //cout << s << endl;
            ans.push_back(s);
            return;
        }
        if (left == n)
        {
            string str = s;
            for (int i = 0; i < 2*n - depth;i++)
            {
                s += ')';
            }
            dfs(s, n, 2*n, n);
            s = str;
        }
        else if (depth == 2 * left){ //左右括号都是比配的,只能加左括号了
            string str = s;
            s += "(";
            dfs(s, left + 1, depth + 1, n);
            s = str;
        }
        else{

            string str = s;
            s += "(";
            dfs(s, left + 1, depth + 1, n);
            s = str;

            str = s;
            s += ")";
            dfs(s, left, depth + 1, n);
            s = str;
        }
    }

    vector<string> generateParenthesis(int n) {
        string s = "(";
        dfs(s, 1,1, n);
        return ans;
    }
};

class Solution {
public:
    vector<string> ans;

    void dfs(string &s , int leftCnt, int totalCnt, int n)
    {
        if(leftCnt > n || totalCnt > 2*n)
            return;

        int rightCnt = totalCnt - leftCnt;
        if(rightCnt > leftCnt)
            return;

        if(leftCnt == n && totalCnt == 2*n)
        {
            ans.push_back(s);
            //cout << s << endl;
            return;
        }

        if(leftCnt < n)
        {
            string tmp = s;
            s += ")";
            dfs(s, leftCnt, totalCnt + 1, n);
            s = tmp + "(";
            dfs(s, leftCnt + 1, totalCnt + 1, n);
        }else{
            s += ")";
            dfs(s, leftCnt, totalCnt + 1, n);
        }
    }
    vector<string> generateParenthesis(int n) {

        string s = "(";
        dfs(s, 1, 1, n);

        return ans;
    }
};

279. Perfect Squares

题目地址

https://leetcode.com/problems/perfect-squares/

题目描述

Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16, …) which sum to n.

For example, given n = 12, return 3 because 12 = 4 + 4 + 4; given n = 13, return 2 because 13 = 4 + 9.

ac (bfs 记忆)

class Solution {
public:

    int bfs(vector<int> &nums, int len , int n)
    {
        vector<bool> vis(n+1,false);

        queue<int> que;
        queue<int> queCeng;
        que.push(0);
        queCeng.push(0);

        vis[0] = true;

        while(!que.empty())
        {
            int curSum = que.front();
            que.pop();
            int curCeng = queCeng.front();
            queCeng.pop();

            if(curSum == n){
                return curCeng;
            }

            for(int i=0;i<len;i++)
            {
                if(curSum + nums[i] <= n && vis[curSum + nums[i]] == false)
                {
                    vis[curSum + nums[i]] = true;
                    que.push(curSum + nums[i]);
                    queCeng.push(curCeng + 1);
                }
            }
        }

        return -1;
    }

    int numSquares(int n) {

        vector<int> nums;
        int len = 0;
        int i = 1;
        while(i * i <= n)
        {
            nums.push_back(i*i);
            len ++;
            i++;
        }

        if(nums[len - 1] == n)
        {
            return 1;
        }
        return bfs(nums, len, n);
    }
};

491. Increasing Subsequences

题目地址

https://leetcode.com/problems/increasing-subsequences/

ac

排了序的话
是可以按照
/*if(i > index && num[i] == num[i-1])
continue;*/
但如果本身就是无序的话,应该是不可以的,仍然会有重复的情况出现

DFS ac代码

class Solution {
public:

    vector<vector<int>> ans;
    vector<int> rs;
    set<vector<int>> se;

    vector<int> num;
    int len;

    void dfs(int curNum, int index,int curLen)
    {
        if(curLen >= 2)
        {
            //ans.push_back(rs);
            se.insert(rs);
        }

        for(int i= index ;i < len;i++)
        {
            /*if(i > index && num[i] == num[i-1])
                continue;*/

            if(num[i] >= curNum)
            //if(rs.size() == 0 || num[i] >= rs[rs.size() - 1])
            {
                rs.push_back(num[i]);
                dfs(num[i], i+1, curLen + 1);
                rs.pop_back();
            }
        }
    }

    vector<vector<int>> findSubsequences(vector<int>& nums) {
        len = nums.size();
        num = nums;

        if(len < 2)
            return ans;

        int maxx = 0x7fffffff;
        int minn = -1 - maxx;

        dfs(minn, 0, 0);

        for(auto it=se.begin();it!=se.end();it++) 
            ans.push_back(*it);  

        return ans;
    }
};

#

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值