题目链接:分割回文串

给你一个字符串 s,请你将 s 分割成一些 子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。

方法一:DFS+逗号分割

class Solution {
public:
    vector<vector<string>> ans;
    vector<string> path;
    bool is_hw(string s,int start,int end) {
        while (start < end) {
            if (s[start++] != s[end--]) return false;
        }
        return true;
    }
    void dfs(string s,int start,int i) {
        if (i == s.size()) {
            ans.push_back(path);
            return ;
        }
        if (i < s.size() - 1) {
            dfs(s,start,i+1);
        }
        if (is_hw(s,start,i)) {
            path.push_back(s.substr(start,i-start+1));
            dfs(s,i+1,i+1);
            path.pop_back();
        }
    }
    vector<vector<string>> partition(string s) {
        dfs(s,0,0);
        return ans;
    }
};

方法二:DFS+遍历

class Solution {
public:
    vector<vector<string>> ans;
    vector<string> path;
    bool is_hw(string s,int start,int end) {
        while (start < end) {
            if (s[start++] != s[end--]) return false;
        }
        return true;
    }
    void dfs(string s,int i) {
        if (i == s.size()) {
            ans.push_back(path);
            return ;
        }
        for (int j = i;j < s.size();j++) {
            if (!is_hw(s,i,j)) continue;
            path.push_back(s.substr(i,j-i+1));
            dfs(s,j+1);
            path.pop_back();
        }
    }
    vector<vector<string>> partition(string s) {
        dfs(s,0);
        return ans;
    }
};

方法三:DP+DFS

class Solution {
public:
    vector<vector<string>> ans;
    vector<string> path;
    vector<vector<bool>> isPal;
    void buildPal(string s) {
        isPal.assign(s.size(),vector<bool>(s.size(),false));
        for (int i = s.size() - 1;i >= 0;i--) {
            for (int j = i;j < s.size();j++) {
                if (s[i] == s[j] && (j-i <= 2 || isPal[i+1][j-1])) {
                    isPal[i][j] = true;
                }
            }
        }
    }
    void dfs(string s,int i) {
        if (i == s.size()) {
            ans.push_back(path);
            return ;
        }
        for (int j = i;j < s.size();j++) {
            if (!isPal[i][j]) continue;
            path.push_back(s.substr(i,j-i+1));
            dfs(s,j+1);
            path.pop_back();
        }
    }
    vector<vector<string>> partition(string s) {
        buildPal(s);
        dfs(s,0);
        return ans;
    }
};

题目链接:括号生成

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。

方法一:递归

class Solution {
public:
    vector<string> generateParenthesis(int n) {
        dfs("",n,n);
        return res;
    }
    vector<string> res;
    void dfs(const string& str,int left,int right) {
        if (left < 0 || left > right) return ;
        if (left == 0 && right == 0) {
            res.push_back(str);
            return ;
        }
        dfs(str + '(',left - 1,right);
        dfs(str + ')',left,right - 1);
    }
};

题目链接:前 K 个高频元素

给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。

方法一:桶排序

class Solution {
public:
    vector<int> topKFrequent(vector<int>& nums, int k) {
        unordered_map<int,int> cnt;
        int max_cnt = 0;
        for (int x : nums) {
            cnt[x]++;
            max_cnt = max(max_cnt,cnt[x]);
        }
        vector<vector<int>> buckets(max_cnt+1);
        for (auto& [x,c] : cnt) {
            buckets[c].push_back(x);
        }
        vector<int> ans;
        for (int i = max_cnt;i >= 0 && ans.size() < k;i--) {
            ans.insert(ans.end(),buckets[i].begin(),buckets[i].end());
        }
        return ans;
    }
};

题目链接:数组中的第K个最大元素

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。

请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。

方法一:快速选择

class Solution {
public:
    int quickSelect(vector<int>& nums,int k) {
        int pivot = nums[rand() % nums.size()];
        vector<int> big,equal,small;
        for (int num : nums) {
            if (num > pivot) {
                big.push_back(num);
            }else if (num < pivot) {
                small.push_back(num);
            }else {
                equal.push_back(num);
            }
        }
        if (k <= big.size()) {
            return quickSelect(big,k);
        }
        if (nums.size() - small.size() < k) {
            return quickSelect(small,k - nums.size() + small.size());
        }
        return pivot;
    }
    int findKthLargest(vector<int>& nums, int k) {
        return quickSelect(nums,k);
    }
};

题目链接:柱状图中最大的矩形

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。

求在该柱状图中,能够勾勒出来的矩形的最大面积。

方法一:单调栈

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        heights.insert(heights.begin(),0);
        heights.push_back(0);
        stack<int> s;
        int res = 0;
        for (int i = 0;i < heights.size();i++) {
            while (s.size() && heights[s.top()] > heights[i]) {
                int cur = s.top();
                s.pop();
                res = max(res,(i - 1 - s.top()) * heights[cur]);
            }
            s.push(i);
        }
        return res;
    }
};