- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
有人能帮我解决这个问题吗?我将把问题打出来,然后给出我的一些想法/其他解决方案。
所以问题是,给定一个像这样的括号字符串:
[[]]
[[]]
1.1111
2.2222
3.1221
4.2112
5.1212
6.2121
"[]" = 2
"[[]]" = 6
"[[]]" = 20
"[[[[]]]]" = 70
char buf[1000];
int N;
bool isValid(int mask)
{
int lv = 0;
for (int i = 0; i < N; i++)
{
if (mask & (1 << i))
{
if (buf[i] == '(')
{
lv++;
}
else
{
lv--;
}
if (lv<0)
{
return false;
}
}
}
return lv==0;
}
int main()
{
scanf("%s", buf);
N = strlen(buf);
int ways = 0;
for (int i = 0; i < (1 << N); i++)
{
if (isValid(i) && isValid(~i))
{
ways++;
}
}
printf("Number of ways is %d\n", ways);
return 0;
}
最佳答案
给出了C++中的O(n ^ 3)-时间,O(n ^ 2)-空间动态规划解。但是这个算法的合理性首先需要一些解释。在下面,我使用“substring”表示元素的有序子集必须是连续的,“subsequence”表示不需要的有序子集。
生成我们知道有效的字符串
将字符串的深度定义为它包含的[
s个数减去]
s个数。
让我们建立一些所有有效(“平衡”)括号字符串必须遵守的规则:
必须有相等数量的[
s和]
s。
字符串的前缀不能有负深度,即]
s大于[
s。
这些显然是必要的条件——如果一个字符串违反了任一规则,它就不能有效。但是为了能够方便地生成我们知道是有效的字符串,我们需要证明这些条件也足够:任何遵守这些规则的字符串都必须是有效的。为了帮助解决这个问题,让我们介绍一个引理:
引理:如果非空字符串服从条件(1)和(2),则它必须包含[]
作为子字符串。
证明:它必须以[
开头,否则length-1前缀包含的]
s将多于[
s并违反(2)。因此它必须至少包含一个]
,否则将有i>=1[
s和0]
s,并且有效字符串必须包含相等数量的每个by(1)。因此,在j>1的某个位置必须出现第一个a]
,其左边的字符必须是a[
。
假设我们有一个服从条件(1)和(2)的非空字符串x
。根据引理,它必须包含一个[]
。删除此对不会导致违反这些条件中的任何一个,因此生成的字符串如果不是空的,则仍必须遵守条件(1)和(2),因此必须在某处包含[]
。因此,我们可以继续删除[]
s,直到留下空字符串为止。
在任何位置的有效字符串中插入[]
都必须生成新的有效字符串,因为新的括号对总是相互匹配,并且不会干扰任何其他匹配的对。请注意,可以通过重复将x
s插入空字符串(这是非常有效的)来构建原始字符串[]
,其顺序与我们在上一段中删除它们的顺序相反:因此,我们现在已经证明x
(即任何符合条件(1)和(2)的字符串)是有效的。
右递归
一种表达op问题的等价方法是:“我们可以用多少种方法来选择字符位置的有效子序列,以便剩余的子序列也有效?”如果我们首先将其概括为:
假设到目前为止我们选择的子序列具有depthd
,而到目前为止我们未选择的子序列具有depthe
,那么我们可以通过多少种方式从后缀中选择一个有效的子序列,从k
位置开始,以便剩余的子序列也是有效的?
调用此函数count(d, e, k)
。原来的问题现在的答案是count(0, 0, 0)
。
事实上,我们可以通过注意d+e
必须等于k
字符后的总深度来进一步简化问题,因此我们可以从e
和d
中确定k
,count()
只需要两个参数。
此外,在测试是否可以选择空子序列时,我们只需要测试d
==0。我们不需要费心测试e
加上剩余的后缀在不低于它的情况下降到0,因为如果d
==0,那么我们已经从原始字符串中减去了0的净深度(假设它是有效的,它必须以0的深度结束,而不低于0)。
为了递归地解决这个问题,我们需要从搜索所有可能的子序列的过程中分离出第一个决策点。长度为n的字符串的子序列必须属于以下n+1情况之一:它要么为空,要么具有最左边的元素,该元素可以是字符串中的n个字符中的任何一个。在做出第一个决定后通过递归产生的子序列都是不同的。
递归正常工作时,记住它很简单:只需在2d vectormemo[][]
中记录任何给定调用的正确答案,2d vectorcount(d, k)
最初由-1值填充。由于函数if (memo[d][k] == -1) {
有两个参数,对于长度为n的字符串,其范围分别为0到n/2和0到n,因此需要o(n^2)空间,long long
块的内部最多执行o(n^2)次。每当发生这种情况时,O(n)循环运行,将时间复杂度提高到O(n 3)。
实际代码
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class PartitionCounter {
// Return the number of subsequences of the suffix of v beginning at position k
// that are (a) valid, given that the initial depth of the subsequence is d (on
// account of it being the suffix of some larger subsequence), and (b)
// leave behind a remainder subsequence that is also valid, given that
// the remainder sequence has initial depth depths[k]-d.
int count(int d, int k) {
// If a prefix of either sequence (selected or remaining) has more ']'s
// than '['s then there can't be any completing subsequences.
if (d < 0 || depths[k] - d < 0) {
return 0;
}
// Only compute the answer if we haven't already.
if (memo[d][k] == -1) {
// A subsequence must either contain no elements, or a leftmost element
// at some position. All subsequences produced by recursion after this
// initial choice are distinct (when considering the sequence of
// character indices included, though not necessarily when considering
// the sequence of characters themselves).
// Try including no elements. This effectively terminates the larger
// subsequence that the selected subsequence is part of, so it can be
// legal only if its depth is 0. It also effectively includes all
// remaining characters in the remainder sequence, but if the selected
// subsequence has depth 0 and the original string does too, then it's
// implied that the remainder must also have total depth 0, so we don't
// need to check it.
int n = (d == 0);
// Try including a leftmost element at each remaining position.
// If this would cause a remainder subsequence that has negative
// depth, stop: any later loop iterations would also create illegal
// remainder subsequences.
for (int i = k; i < v.size() && depths[i] - d >= 0; ++i) {
n += count(d + v[i], i + 1);
}
memo[d][k] = n;
}
return memo[d][k];
}
vector<int> v; // 1 for '[', -1 for ']'
vector<int> depths; // depths[i] is the sum of the 1st i elements
vector<vector<int> > memo; // DP matrix. -1 => not computed yet
public:
PartitionCounter(string s) : memo(s.size() / 2 + 1, vector<int>(s.size() + 1, -1)) {
depths.push_back(0);
int total = 0;
for (int i = 0; i < s.size(); ++i) {
v.push_back(1 - 2 * (s[i] == ']')); // Map '[' to 1 and ']' to -1
depths.push_back(total += v[i]);
}
}
int count() {
if (depths.back() == 0) {
return count(0, 0);
} else {
return 0; // Need to handle invalid strings specially
}
}
};
int main(int argc, char **argv) {
PartitionCounter c(argv[1]);
cout << c.count() << '\n';
}
C:\>partitioncounter []
2
C:\>partitioncounter [[]]
6
C:\>partitioncounter [[[]]]
20
C:\>partitioncounter [[[[]]]]
70
C:\>stopwatch partitioncounter [][[[[[][][][][[][][]]]]]][]
10001208
stopwatch: Terminated. Elapsed time: 15ms
stopwatch: Process completed with exit code 0.
C:\>stopwatch partitioncounter [][[[[[][[[]][][][[]]][[][]]]]]][]
562547776
stopwatch: Terminated. Elapsed time: 0ms
stopwatch: Process completed with exit code 0.
int
或其他方式代替
]
。
[
s大于
关于algorithm - 分割一串括号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13437005/
IntelliJ 有没有办法删除周围的括号、括号、引号等?例如,如果我有: "string" 有没有办法删除匹配的引号并得到这个? string 最佳答案 不是直接的,但以下替换表达式(ctrl+R,
我有一段代码是这样的; var x(10); var i = 3; x(i) = 7 document.write("The stored value is " + x(3) +" 这是我正在阅读的书
括号在sql语句中的作用是什么? 例如,在声明中: 插入 table1 ([columnname1], columnname2) 值 (val1, val2) 另外,如果表名在括号中,它会做什么? 最
为什么在“java”中,当你声明“注释”的“参数”时,必须在参数后面放置“一对括号”,注释在语法上与“接口(interface)”形式“非常不同”,所以为什么这很奇怪语法...我知道这与注释是使用幕后
我正在尝试实现后缀到中缀和中缀到后缀(使用堆栈),一切都很顺利,除了当我从后缀转换时我无法想出如何处理括号的想法。它说我必须使用最少数量的括号。例如: ab+c*da-fb-*+ (a+b)*c+
我有这样的数据: $json_data_array = '[ { "id": 1, "value": "hr@test.com",
我有一个字符串,其中包含数字周围的方括号 []。由于此字符串代表我的 SQL 数据库的列名称,因此我需要删除/替换它们。到目前为止,我通过以下方式进行: if (stringWithBracket.C
这是 index.js 文件的代码快照,它是在新的 phonegap 项目中默认创建的。 var app = { // Application Constructor initiali
您好,先生,我正在通过 url 将数组列表 android 发送到 php,它也成功插入,但是 start[ 和 end ] 这个小括号也插入了,我想删除它 我尝试以下代码.. 请告诉我如何删除括号
我正在尝试将 css 括号括在我的 h2 标题周围(大概 90% 都在那里),但我在解决一些小问题时遇到了麻烦: 1. 右边线的间距有点偏,应该拿过来与支架连接。我该如何调整? 和 2. 通过 bg.
有人能给我一些关于这个问题的提示吗:仅当表达式包含正确闭合的圆括号和大括号并且没有其他字符(甚至空格)时,它才是正确的。例如,() ({} () ({})) 是正确的表达式,而 ({)} 不是正确的表
这怎么让宽度变成 100%? .test { width: (50%;); } 我已经知道如何修复它,使其变为 50%,并且该语句或多或少是多余的,我只想知道为什么会发生这种情况。 编辑:ht
请问python的语法本质上df.head()和df.head有什么区别?我可以解释为前一个是用于调用方法,而后一个只是试图获取DataFrame的属性,即头部?我很困惑为什么有时末尾有括号但有时
我通过C#阅读了一些MSDN文档,发现一段代码可以在字符串构造函数和字符串本身之间使用,就像这样 string[] stringname; 这是什么意思呢? 最佳答案 这只是一个数组声明。这意味着st
是否有人知道在创建 PHP 数组时 [ ] 的含义,以及是否真的需要它。因为从我的角度来看。两种方式都够了 方式一,带括号: $cars[] = array ('expensive' => $BMW,
最近我看到了很多将 SQL 值包含在 {} 中的 PHP/MySQL 问题,例如: SELECT * FROM table WHERE field LIKE '{$value}'; 这是怎么回事?它甚
Pattern pattern = Pattern.compile("([a-zA-Z]+)") Matcher matcher = pattern.matcher("Text"); matcher.
这个问题在这里已经有了答案: Usage of string::c_str on temporary string [duplicate] (2 个答案) 关闭 8 年前。 如果我有一个函数 myf
例如, class BasicTransitionFunction(TransitionFunction[GrammarBasedState]): ... 其中TransitionFunc
这个问题在这里已经有了答案: Is short-circuiting logical operators mandated? And evaluation order? (7 个答案) Safety
我是一名优秀的程序员,十分优秀!