欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Leetcode之 括号生成器

程序员文章站 2022-07-14 17:41:57
...

题目描述

给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。

思路

首先创建基本括号组合"((()))",之后对该括号调换顺序获得更多组合:

  1. 首先找到第一个右括号,将其向前一步一步移动直至第一个左括号后,生成的字符串均符合要求,可生成2个,即"(()())“和”()(())"
  2. 对第一步生成的字符串,找到第二个右括号,同理,将其向前移动,最终能运动到的位置取决于第一个右括号前有几个左括号,若左括号数大于1个,则这个右括号可以移动至第一个右括号后一位,否则只能移动到第一个右括号第二位
  3. 同理,对第二步得到的字符串继续调整第三个右括号的位置
  4. 直至获得字符串"()()()",根据以上推理得到的最后一个字符串满足该条件,则跳出结束

代码

class Solution {
public:
    int left_count = 0; /*移动第k个右括号前,第k-1个右括号前的左括号个数*/
    int right_flag = 0; /*标记第k个右括号能够移动到的最左位置*/
    int find(string s, int count) /*找到第k个右括号的位置*/
    {
        int nb = 0;
        int i;
        for (i = 0; i < s.size(); i++)
        {
            if (s[i] == '(')
            {
                if (nb < count - 1)
                    left_count++;
            }
            else
            {
                nb++;
                if (nb == count)
                    break;
                else if (nb == count - 1)
                    right_flag = i;
            }
        }
        return i;
    }



    vector<string> generateParenthesis(int n) {
        vector<string> res;
        string tmp;
        string test;
        if (n == 0)
            return res;
        list<string> list_res;
        for (int i = 0; i<n; i++)
        {
            tmp += '(';
        }
        for (int i = 0; i<n; i++)
            tmp += ')';
        for (int i = 0; i<n; i++)
            test += "()"; /*结束条件*/
        list_res.push_back(tmp);/*利用list来记录每步的结果,为下一步做准备*/
        res.push_back(tmp);
        int count = 1;
        int last_push = 1;/*用来记录第k-1步时生成的字符串数目*/
        int pop_count = 0;/*用来记录是否将k-1步生成的字符串处理殆尽*/
        int current_push = 0;
        while (count<n)
        {
            string s1 = list_res.front();
            list_res.pop_front();
            pop_count++;
            left_count = 0;
            int left_max;
            int i = find(s1, count);
            if (count == 1)/*特殊情况特殊处理*/
            {
                left_max = 1;
                i = n ;
            }
            else
            {	
                if (left_count >= count)
                    left_max = right_flag + 1;/*第k个右括号向左移动的目标位置*/
                else
                    left_max = right_flag + 2;
            }
            while (i>left_max)/*移动第k个右括号*/
            {
                char tmp_char = s1[i - 1];
                s1[i - 1] = s1[i];
                s1[i] = tmp_char;
                res.push_back(s1);
                if (s1 == test)
                {
                    return res;/*结束,返回*/
                }
                else
                {
                    list_res.push_back(s1);/*将本次结果压入list*/
                    current_push++;
                }
                i--;
            }
            if (pop_count == last_push)/*判断k-1步的字符串是否处理完*/
            {
                count++;
                last_push = current_push;
                pop_count = 0;
                current_push = 0;
            }
        }
        return res;
    }
};