- 50. Pow(x, n) (medium)">50. Pow(x, n) (medium)
- 22. 括号生成(medium)">22. 括号生成(medium)
50. Pow(x, n) (medium)
实现 pow(x, n) ,即计算 x 的 n 次幂函数。
方法 1(快速幂+递归):
class Solution {
public:
double quickMul(double x, long long N) {
if (N == 0) {
return 1.0;
}
double y = quickMul(x, N / 2);
return N % 2 == 0 ? y * y : y * y * x;
}
double myPow(double x, int n) {
long long N = n;
return N >= 0 ? quickMul(x, N) : 1.0 / quickMul(x, -N);
}
};
22. 括号生成(medium)
方法 1(暴力解):
1、使用递归生成所有序列。
2、对每个序列进行有效判断:使用一个变量 balance 表示左括号的数量减去右括号的数量。如果遍历过程中 balance 的值小于零,或者结束时 balance 的值不为零,那么该序列就是无效的,否则它是有效的。
class Solution {
bool valid(const string& str) {
int balance = 0;
for (char c : str)
if (c == '(')
++balance;
else {
--balance;
if (balance < 0)
return false;
}
return balance == 0;
}
void generate_all(string& current, int n, vector<string>& result) {
if (n == current.size()) {
if (valid(current))
result.push_back(current);
return;
}
current += '(';
generate_all(current, n, result);
current.pop_back();
current += ')';
generate_all(current, n, result);
current.pop_back();
}
public:
vector<string> generateParenthesis(int n) {
vector<string> result;
string current;
generate_all(current, n * 2, result);
return result;
}
};
方法 2(回溯法):
方法一还有改进的余地:我们可以只在序列仍然保持有效时才添加 ‘(‘ or ‘)’,而不是像 方法一 那样每次添加。我们可以通过跟踪到目前为止放置的左括号和右括号的数目来做到这一点,
如果左括号数量不大于 nn,我们可以放一个左括号。如果右括号数量小于左括号的数量,我们可以放一个右括号。
class Solution {
void backtrack(vector<string>& ans, string& cur, int open, int close, int n) {
if (cur.size() == n * 2) {
ans.push_back(cur);
return;
}
if (open < n) {
cur.push_back('(');
backtrack(ans, cur, open + 1, close, n);
cur.pop_back();
}
if (close < open) {
cur.push_back(')');
backtrack(ans, cur, open, close + 1, n);
cur.pop_back();
}
}
public:
vector<string> generateParenthesis(int n) {
vector<string> result;
string current;
backtrack(result, current, 0, 0, n);
return result;
}
};