括号组合的时间复杂度

2023-11-21

我尝试做经典问题来实现一种算法来打印 n 对括号的所有有效组合。

我找到了这个程序(效果很好):

public static void addParen(ArrayList<String> list, int leftRem, int rightRem, char[] str, int count) {
    if (leftRem < 0 || rightRem < leftRem) return; // invalid state

    if (leftRem == 0 && rightRem == 0) { /* all out of left and right parentheses */
        String s = String.copyValueOf(str);
        list.add(s);
    } else {
        if (leftRem > 0) { // try a left paren, if there are some available
            str[count] = '(';
            addParen(list, leftRem - 1, rightRem, str, count + 1);
        }
        if (rightRem > leftRem) { // try a right paren, if there’s a matching left
            str[count] = ')';
            addParen(list, leftRem, rightRem - 1, str, count + 1);
        }
    }
}

public static ArrayList<String> generateParens(int count) {
    char[] str = new char[count*2];
    ArrayList<String> list = new ArrayList<String>();
    addParen(list, count, count, str, 0);
    return list;
}

据我了解,我们的想法是尽可能添加左括号。对于右括号,只有当剩余的右括号数量大于左括号时,我们才会添加它。如果我们使用了所有左括号和右括号,我们会将新组合添加到结果中。我们可以确定不会有任何重复构造的字符串。

对我来说,这种递归就像我们使用树时,例如我们进行前序遍历:我们每次都可能去左节点,如果不行,我们就向右走,然后我们尝试向左走就在这一步之后。如果不能,我们“返回”并向右走,然后重复遍历。在我看来,这里的想法完全相同。

所以,我天真地认为时间复杂度会是 O(log(n))、O(n.log(n)) 或类似对数的东西。但是,当我尝试搜索时,我发现了一个叫做“加泰罗尼亚语数量”的东西,我们可以用它来计算括号组合的数量......(https://anonymouscoders.wordpress.com/2015/07/20/its-all-about-catalan/)

您认为时间复杂度是多少?我们可以在这里应用主定理吗?


此代码的复杂度为 O(n * Cat(n)),其中 Cat(n) 是第 n 个加泰罗尼亚数字。有 Cat(n) 个可能的有效字符串,它们是括号的有效组合(请参阅https://en.wikipedia.org/wiki/Catalan_number),并为每个创建一个长度为 n 的字符串。

由于 Cat(n) = 选择(2n, n) / (n + 1),因此 O(n * Cat(n)) = O(选择(2n, n)) = O(4^n / sqrt(n)) (看https://en.wikipedia.org/wiki/Central_binomial_coefficient).

你的推理有两个主要缺陷。首先是搜索树不平衡:关闭右大括号时搜索的树与添加另一个左大括号时搜索的树大小不同,因此更常见的计算复杂性的方法不起作用。第二个错误是,即使你假设树是平衡的,height搜索树的长度为 n,找到的叶子数量为 O(2^n)。这与二叉搜索树的分析不同,二叉搜索树中通常有 n 个东西,高度为 O(log n)。

我不认为这里有任何标准的方法来计算时间复杂度——最终你将重现像计算有效括号字符串时所做的数学运算一样的东西——而主定理不会帮助你完成那。

但这里有一个有用的见解:如果一个程序生成 f(n) 个东西,并且生成每个 if c(n) 的成本,那么程序的复杂度不可能比 O(c(n)f(n) 更好)。这里,f(n) = Cat(n) 和 c(n) = 2n,因此即使分析代码很困难,您也可以快速获得复杂性的下限。这个技巧会立即让你放弃复杂度为 O(log n) 或 O(n log n) 的想法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

括号组合的时间复杂度 的相关文章

  • 从原点开始在离散 2D 网格上迭代向外螺旋的算法

    例如 这是预期螺旋的形状 以及迭代的每个步骤 y 16 15 14 13 12 17 4 3 2 11 18 5 0 1 10 x 19 6 7 8 9 20 21 22 23 24 其中线条是 x 轴和 y 轴 以下是算法每次迭代 返回
  • 检查有效的 IMEI

    有人知道如何检查有效的 IMEI 吗 我找到了一个可以检查此页面的功能 http www dotnetfunda com articles article597 imeivalidator in vbnet aspx http www do
  • Python Pandas:沿一列比较两个数据帧,并返回另一个数据帧中两个数据帧的行内容

    我正在处理两个 csv 文件并作为数据框 df1 和 df2 导入 df1 有 50000 行 df2 有 150000 行 我想将 df2 的 时间 与 df1 求时间差并返回所有列的值 对应相似的行 保存在df3中 时间同步 例如 35
  • 分而治之算法找到两个有序元素之间的最大差异

    给定一个整数数组 arr 找出任意两个元素之间的差异 使得较大的元素出现在 arr 中较小的数字之后 Max Difference Max arr x arr y x gt y 例子 如果数组是 2 3 10 6 4 8 1 7 那么返回值
  • 如何在 C# 中以编程方式创建柔和的颜色?

    根据所需的颜色数量均匀分布地生成它们 如果指定的计数为 8 则看起来像这样 List
  • heapq.nlargest 的时间复杂度是多少?

    我在看演讲者说 获得t列表中最大的元素n元素可以在O t n 这怎么可能 我的理解是创建堆将是O n 但是复杂度是多少nlargest本身就是O n t or O t 实际的算法是什么 在这种情况下 说话者是错误的 实际成本是O n log
  • Java 2d 游戏中的路径查找?

    本质上它是我正在开发的一款吃豆人克隆游戏 我有一个 Enemy 类 并创建了该类的 4 个实例 它们都代表游戏的 4 个幽灵 所有幽灵都会在屏幕的随机区域启动 然后它们必须朝着吃豆人角色前进 当玩家控制吃豆人并移动它时 他们应该跟随它并尽可
  • 为什么这个算法的Big-O复杂度是O(n^2)?

    我知道这个算法的大O复杂度是O n 2 但我不明白为什么 int sum 0 int i 1 j n n while i lt j sum 即使我们设定了j n n一开始 我们在每次迭代期间递增 i 并递减 j 因此最终的迭代次数不应该比n
  • 如何计算 3D Morton 数(交织 3 个整数的位)

    我正在寻找一种快速计算 3D Morton 数的方法 这个网站 http www graphics stanford edu seander bithacks html InterleaveBMN有一个基于幻数的技巧来处理 2D Morto
  • 删除近排序数组中未排序/离群元素

    给定一个像这样的数组 15 14 12 3 10 4 2 1 我如何确定哪些元素乱序并删除它们 在本例中为数字 3 我不想对列表进行排序 而是检测异常值并将其删除 另一个例子 13 12 4 9 8 6 7 3 2 我希望能够删除 4 和
  • 为什么 Dijkstra 算法使用减密钥?

    Dijkstra 教给我的算法如下 while pqueue is not empty distance node pqueue delete min if node has been visited continue else mark
  • 面试题:三个数组,O(N*N)

    假设我们有three长度数组N其中包含任意数量的类型long 然后我们得到一个数字M 相同类型 我们的任务是选择三个数字A B and C每个数组中的一个 换句话说A should从第一个数组中选取 B从第二个开始和C从第三个 所以总和A
  • 表达式的大 O 表示法

    如果我有一个需要 4n 2 7n 步才能完成的算法 它的 O 是多少 O 4n 2 O n 2 我知道 7n 被截断 但我不知道是否应该保留 n 2 系数 Thanks 您应该删除任何系数 因为问题实际上是在 按顺序 询问 它试图将其描述为
  • 排序矩阵的选择算法

    这是谷歌面试问题 给定一个 N N 矩阵 所有行均已排序 所有列均已排序 找到矩阵的第 K 个最大元素 在 n 2 中执行它很简单 我们可以使用堆或合并排序 n lg n 对它进行排序 然后得到它 但是有没有更好的方法 比 n lg n 更
  • 在工作表中合并行和求和值

    我有一个 Excel 工作表 其中包含以下数据 管道 来分隔列 A B C X 50 60 D E F X 40 30 A B C X 10 20 A B C Y 20 20 A B C X 20 70 D E F X 10 50 A B
  • 颜色变换器功能上的堆栈溢出错误

    我有两种颜色 红色 和 鲑鱼色 我需要动态创建面板以及面板背景颜色 这些颜色必须介于两种颜色之间 红色 public Color x y protected void Page Load object sender EventArgs e
  • 调度算法,找到设定长度的所有非重叠区间

    我需要为我的管理应用程序实现一种算法 该算法将告诉我何时可以将任务分配给哪个用户 我实现了一个蛮力解决方案 它似乎有效 但我想知道是否有更有效的方法来做到这一点 为了简单起见 我重写了算法以对数字列表进行操作 而不是数据库查询等 下面我将尝
  • 从给定的项目列表创建子列表

    我首先要说的是以下问题不是为了家庭作业目的即使因为我几个月前就完成了软件工程师的工作 无论如何 今天我正在工作 一位朋友向我询问了这个奇怪的排序问题 我有一个包含 1000 行的列表 每行代表一个数字 我想创建 10 个子列表 每个子列表都
  • while循环的时间复杂度是多少?

    我正在尝试找出 while 循环的时间复杂度 但我不知道从哪里开始 我了解如何找到 for 循环的复杂性类别 但是当涉及到 while 循环时 我完全迷失了 关于从哪里开始有什么建议 提示吗 这是一个问题的示例 x 0 A n some a
  • 如何以最低的价格优化购物车?

    我有一个我想买的物品清单 这些商品由不同的商店提供 价格也不同 商店有单独的送货费用 我正在寻找一种最佳的购物策略 以及支持它的java库 以最低的总价购买所有商品 Example 商品 1 在 Shop1 的售价为 100 美元 在 Sh

随机推荐

  • C++中的函数指针赋值和调用?

    我知道当我们使用函数名称作为值时 该函数会自动转换为指针 看下面的代码 int print int a return a int main int p int print int q int print cout lt lt p 8 lt
  • PHP 正则表达式验证字母和西班牙口音

    我如何添加 临时修改我的代码 以便除了正常字母表 a z 之外 西班牙口音也被视为有效 我的代码中有以下内容 public static function IsAlpha s reg a z s i count preg match reg
  • 在Python中删除字符串中间的连续字符[重复]

    这个问题在这里已经有答案了 从字节转换为字符串后 Google 地图 API 的标准返回值如下所示 b n destination addresses Washington DC USA n origin addresses New Yor
  • 在 java (JSP) 中提取 .tar.gz 文件

    我似乎无法导入所需的包或找到任何有关如何提取的在线示例 tar gzjava 中的文件 更糟糕的是我正在使用 JSP 页面 并且在将包导入到我的项目中时遇到问题 我正在将 jar 复制到WebContent WEB INF lib 然后右键
  • Typescript 方法装饰器

    我有这个代码 function changeFunc return function target any title string descriptor PropertyDescriptor descriptor value functi
  • Python 不向多个地址发送电子邮件

    我看不出我哪里出了问题 我希望有人能发现这个问题 我想向多个地址发送电子邮件 但是 它仅将其发送到列表中的第一个电子邮件地址 而不是同时发送到两者 这是代码 import smtplib from smtplib import SMTP r
  • 检测用户所做的屏幕分辨率更改(Java Listener?)

    我有一个 Java 应用程序 可以启动 创建 GUI 并且运行良好 如果用户更改屏幕分辨率 从 1440x900 切换到 1280x768 我希望能够侦听该事件 有任何想法吗 PS 我想在事件 侦听器模式下执行此操作 而不是在轮询模式下执行
  • sbt-assemble 包括测试类

    我跟随sbt assemble 包括测试类来自中描述的配置https github com sbt sbt assemble组装工作正常 当我加载 sbt 时我得到 assembly sbt 5 error reference to jar
  • 卸载动态库需要两次 dlclose() 调用?

    我有一个动态库 我使用它加载dlopen 然后使用卸载dlclose 如果我不包含任何目标 C 代码dlopen 需要一个dlclose 调用这是预期的行为 但是当我包含任何目标 c 代码作为目标时 我遇到的问题是我需要做两件事dlclos
  • 无法在 Eclipse 中创建新的 FXML 文件

    当我尝试在 Eclipse 中创建一个新的 FXML 文件 文件 gt 新建 gt 其他 gt JavaFX 新的 FXML 文档 gt 下一步 时 什么也没有发生 它不创建文件 当我尝试创建 FXGraph 或 JavaFX HTML 模
  • 使用.NET Core从Azure表存储中检索前n条记录

    是否可以使用 C 从 Azure 表存储中检索前 n 条记录 我正在使用 NET Core 如果我也能得到一些参考资料那就太好了 请注意 我的所有实体都是使用 Log Tail 模式存储的https learn microsoft com
  • 我使用了 matplotlib,但图形中出现了错误消息“

    import matplotlib pyplot as plt from matplotlib import font manager rc f name font manager FontProperties fname C Window
  • C++中map的初值假设

    我正在初始化地图map
  • Pandas/Numpy NaN 无比较

    Python Pandas 和 Numpy 中 为什么比较结果不同 from pandas import Series from numpy import NaN NaN不等于NaN gt gt gt NaN NaN False but N
  • 如何将我的 Node.js 客户端连接限制为 2 个?

    我基本上试图只允许 2 个客户端同时连接到该应用程序 我应该如何处理这个问题 这是我的服务器代码 var express require express app express server require http createServe
  • LabelEncoder 将缺失值保留为“NaN”

    我正在尝试使用标签编码器将分类数据转换为数值 我需要一个 LabelEncoder 将缺失值保留为 NaN 以便之后使用 Imputer 所以我想在像这样标记后使用掩码来替换原始数据框 df pd DataFrame A x np NaN
  • NSOpenPanel 作为工作表

    我环顾四周的其他答案 但似乎没有什么可以帮助我的情况 我有一个 viewController 类 其中包含按钮的 IBAction 此按钮应该从该 viewController 打开一个 NSOpenPanel 作为工作表 class Vi
  • Angular 在父组件嵌套表单中使用子组件表单

    将子组件表单放入父组件表单的最佳方法是什么 我们使用的是2019年最新的Angular 8 经过研究 以下方法并不完全有效 父组件 ngOnInit this parentForm this fb group childForm1 etc
  • 我可以在过程中传递游标吗?

    我可以在过程中传递游标吗 CURSOR BLT CURSOR IS SELECT BLT sol id BLT bill id BLT bank id FROM BLT 是我的光标 Procedure abc i want to pass
  • 括号组合的时间复杂度

    我尝试做经典问题来实现一种算法来打印 n 对括号的所有有效组合 我找到了这个程序 效果很好 public static void addParen ArrayList