classSolution {
public:
intlongestValidParentheses(string s){
int ret = 0;
stack<int> stk;
stk.push(-1);
for (int i = 0; i < s.size(); ++i) {
if (s[i] == '(') {
stk.push(i);
} else {
stk.pop();
if (stk.empty()) {
stk.push(i);
} else {
ret = max(ret, i - stk.top());
}
}
}
return ret;
}
};
解法三:无需额外空间
classSolution {
public:
intlongestValidParentheses(string s){
int left = 0, right = 0, maxlength = 0;
for (int i = 0; i < s.size(); i++) {
if (s[i] == '(') {
left++;
} else {
right++;
}
if (left == right) {
maxlength = max(maxlength, 2 * right);
} elseif (right > left) {
left = right = 0;
}
}
left = right = 0;
for (int i = (int)s.size() - 1; i >= 0; i--) {
if (s[i] == '(') {
left++;
} else {
right++;
}
if (left == right) {
maxlength = max(maxlength, 2 * left);
} elseif (left > right) {
left = right = 0;
}
}
return maxlength;
}
};
33. 搜索旋转排序数组
难度:中等
标签:二分查找
classSolution {
public:
intsearch(vector<int>& nums, int target){
int n = nums.size();
if (!n) { return-1; }
if (n == 1) { return nums[0] == target ? 0 : -1; }
int left = 0, right = n - 1;
while (left <= right) {
int mid = (right + left) / 2;
if (nums[mid] == target) { return mid; }
if (nums[0] <= nums[mid]) {
if (nums[0] <= target && target < nums[mid]) {
right = mid - 1;
} else {
left = mid + 1;
}
} else {
if (nums[mid] < target && target <= nums[n - 1]) {
left = mid + 1;
} else {
right = mid - 1;
}
}
}
return-1;
}
};
34. 在排序数组中查找元素的第一个和最后一个位置
难度:中等
标签:二分查找
classSolution {
public:
vector<int> searchRange(vector<int>& nums, int target){
if (nums.size() == 0) { return {-1, -1}; }
int left = 0, right = nums.size() - 1;
int begin = 0, end = 0;
// 二分左端点while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] < target) {
left = mid + 1;
} else {
right = mid;
}
}
// 判断结果if (nums[right] != target) { return {-1, -1}; }
else { begin = left; }
// 二分右端点
left = 0; right = nums.size() - 1;
while (left < right) {
int mid = left + (right - left + 1) / 2;
if (nums[mid] > target) {
right = mid - 1;
} else {
left = mid;
}
}
end = left;
return {begin, end};
}
};
35. 搜索插入位置
难度:简单
标签:二分查找、数组
classSolution {
public:
intsearchInsert(vector<int>& nums, int target){
int left = 0, right = nums.size() - 1;
if (nums[right] < target) return right + 1;
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] < target) left = mid + 1;
else right = mid;
}
return left;
}
};
classSolution {
public:
string countAndSay(int n){
string ret = "1";
for (int i = 1; i < n; i++) {
string tmp;
int len = ret.size();
for (int left = 0, right = 0; right < len;) {
while (right < len && ret[left] == ret[right]) {
right++;
}
tmp += to_string(right - left) + ret[left];
left = right;
}
ret = tmp;
}
return ret;
}
};
39. 组合总和
难度:中等
标签:数组、回溯
classSolution {
private:
vector<vector<int>> ret;
vector<int> path;
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
dfs(candidates, 0, target);
return ret;
}
voiddfs(vector<int>& candidates, int pos, int target){
if (target == 0) {
ret.push_back(path);
return;
}
if (target < 0) { return; }
for (int i = pos; i < candidates.size(); i++) {
path.push_back(candidates[i]);
dfs(candidates, i, target - candidates[i]);
path.pop_back();
}
}
};
classSolution {
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
vector<vector<int>> solutions;
vector<int> solution;
int curSum = 0;
dfs(solutions, solution, curSum, 0, target, candidates);
return solutions;
}
voiddfs(vector<vector<int>>& solutions, vector<int>& solution, int curSum, int preIdx, int target, vector<int>& candidates){
if (curSum >= target) {
if (curSum == target) { // 保存当前组合
solutions.push_back(solution);
}
return;
}
// 从后选一个数字累加for (int i = preIdx; i < candidates.size(); i++) {
solution.push_back(candidates[i]);
dfs(solutions, solution, curSum + candidates[i], i, target, candidates);
// 回溯
solution.pop_back();
}
}
};
40. 组合总和 Ⅱ
难度:中等
标签:数组、回溯
classSolution {
private:
vector<pair<int, int>> freq;
vector<vector<int>> ret;
vector<int> path;
public:
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
sort(candidates.begin(), candidates.end());
for (int num : candidates) {
if (freq.empty() || num != freq.back().first) {
freq.emplace_back(num, 1);
} else {
++freq.back().second;
}
}
dfs(0, target);
return ret;
}
voiddfs(int pos, int target){
if (target == 0) {
ret.push_back(path);
return;
}
if (pos == freq.size() || target < freq[pos].first) { return; }
dfs(pos + 1, target);
int most = min(target / freq[pos].first, freq[pos].second);
for (int i = 1; i <= most; i++) {
path.push_back(freq[pos].first);
dfs(pos + 1, target - i * freq[pos].first);
}
for (int i = 1; i <= most; i++) {
path.pop_back();
}
}
};