<<The algorithm is beautiful>>——(4)——Deep recursion

content

legal parentheses

all subsets


legal parentheses

 Idea: First, we have to find out the law, and then write the recursive formula. In this question, by drawing a picture, we will get Sn={Add left, right, and package to each element in Sn-1. Left and right will definitely be repeated. We can use the set in the STL standard library to deduplicate.

recursion

#include<iostream>
#include<set>
using namespace std;
set<string> generateParenthesis(int n) {
    set<string> s_n;
    if (n == 1)
    {
        s_n.insert("()");
        return s_n;
    }
    set<string> s_n_1 = generateParenthesis(n - 1);
    for (string eofn_1 : s_n_1)
    {
        s_n.insert("()" + eofn_1);
        s_n.insert(eofn_1 + "()");
        s_n.insert("(" + eofn_1 + ")");
    }
    return s_n;
}
int main()
{
    set<string> generateParenthesis1 = generateParenthesis(4);
    for (set<string>::iterator it = generateParenthesis1.begin(); it != generateParenthesis1.end(); it++)
     {
         cout << *it << " ";
     }
    return 0;
}

iterate


set<string> generateParenthesis2(int n) {
    set<string> res;
    res.insert("()");
    if (n == 1)
    {
        return res;
    }
    for (int i = 2; i <= n; i++)
    {
        set<string> res_new;
        for (string e : res)
        {
            res_new.insert(e + "()");
            res_new.insert("()" + e);
            res_new.insert("(" + e + ")");
        }
        res = res_new;
    }
    return res;
}

A small test

 Bracket generation


all subsets

 

Ideas:

If there are n elements in the set, it takes n steps to determine the subset of the set. Each step needs to take an element from the collection, and there are two choices at this time, add the current number or not. Generating a subset requires several steps, and each step has several choices, which is a typical problem for applying backtracking.

The helper function in the code has four parameters, the first parameter is the original array nums, the second parameter is the index index of the number currently to be selected in the nums array, the third parameter is the current subset cur, the fourth parameter is The parameter is the set ret of currently generated subsets.

There are currently two options for numbers at subscript index within the nums array. The first is not to consider joining, then you can skip it directly and call the recursive function to judge the case of index + 1. The second is to consider joining, then add the number to the current subset cur, and then call the recursive function to judge the index + 1 situation. After the recursive function is executed, the added number needs to be deleted, so as to make the current subset cur The value remains the same after entering the current recursive function and after executing the current recursive function.

recursion

class Solution {
private:
    void helper(vector<int>& nums, int index, vector<vector<int>>& ret, vector<int>& cur) {
        if (index == nums.size()) {
            ret.emplace_back(cur);
            return;
        }
        // 不加入第 index 个数字
        helper(nums, index + 1, ret, cur);

        // 加入第 index 个数字
        cur.push_back(nums[index]);
        helper(nums, index + 1, ret, cur);
        cur.pop_back();
    }

public:
    vector<vector<int>> subsets(vector<int>& nums) {
        vector<vector<int>> ret;
        vector<int> cur;
        helper(nums, 0, ret, cur);
        return ret;
    }
};

Guess you like

Origin blog.csdn.net/m0_58367586/article/details/123857240