四数之和 中等
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
sort(nums.begin(),nums.end());
vector <vector<int>> res;
for(int i = 0; i + 3 < nums.size(); ++i){
if(i > 0 && nums[i] == nums[i-1])
continue;
for(int j = i+1; j + 2 < nums.size(); ++j){
if(j > i+1 && nums[j] == nums[j-1])
continue;
//此处不能为j>0,循环至少进行一轮后才能continue,确保当前情况已经判断过
int ttarget = target - nums[i] - nums[j] ;
int l = j+1, r = nums.size()-1;
while(l < r){
int sum = nums[l] + nums[r]; //注意-号
if(ttarget == sum){
res.push_back({nums[i],nums[j],nums[l],nums[r]});
l++; r--;
while(l < r && nums[l] == nums[l-1]) l++;
while(l < r && nums[r] == nums[r+1]) r--;
}
if(ttarget > sum) l++;
if(ttarget < sum) r--;
}
}
}
return res;
}
};
寻找峰值 中等
暂时还不知道二分法有什么好的模板
细节是魔鬼
class Solution {
public:
int findPeakElement(vector<int>& nums) {
int left = 0;
int right = nums.size()-1;
while(left < right){
int mid = (right + left) / 2;
if (nums[mid] > nums[mid+1])
right = mid;
else
left = mid + 1;
}
return left;
}
};
- 二叉树的直径 简单
class Solution {
int ans = 0;
int depth(TreeNode* root){
if (root == NULL)
return 0;
int l = depth(root->left);
int r = depth(root->right);
ans = max(ans, l+r);
return max(l, r)+1;
}
public:
int diameterOfBinaryTree(TreeNode* root) {
if (root == NULL) return 0;
depth(root);
return ans;
}
};
组合总和
class Solution {
public:
vector<vector<int>> res;
void backTrack(int now, int sum, int target, vector<int> temp, vector<int>& candidates){
if(sum > target) return;
if(sum == target){
res.push_back(temp);
return;
}
for(int i=now; i<candidates.size(); i++){
sum += candidates[i];
temp.push_back(candidates[i]);
backTrack(i, sum, target, temp, candidates);
sum -= candidates[i];
temp.pop_back();
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target){
vector<int> temp;
backTrack(0, 0, target, temp, candidates);
return res;
}
};
旋转图像 中等
class Solution {
public:
void rotate(vector<vector<int>>& matrix) {
if (matrix.empty()) return;
int n = matrix.size(); int m = matrix[0].size();
for (int i=0; i<=(n-1)/2; i++){
for (int j=0; j<m/2; j++){
int temp = matrix[i][j];
matrix[i][j] = matrix[n-1-j][i];
matrix[n-1-j][i] = matrix[n-1-i][m-1-j];
matrix[n-1-i][m-1-j] = matrix[j][n-1-i];
matrix[j][n-1-i] = temp;
}
}
}
};
实现 Trie (前缀树) 中等
class Trie {
bool flag = false;
Trie* str[26] = {nullptr};
public:
/** Initialize your data structure here. */
Trie() {
}
/** Inserts a word into the trie. */
void insert(string word) {
Trie* root = this;
for (auto c:word){
if (root->str[c-'a'] == nullptr) root->str[c-'a'] = new Trie();
root = root->str[c-'a'];
}
root->flag = true;
}
/** Returns if the word is in the trie. */
bool search(string word) {
Trie* root = this;
for (auto c:word){
if (root->str[c-'a'] == nullptr) return false;
root = root->str[c-'a'];
}
return root->flag;
}
/** Returns if there is any word in the trie that starts with the given prefix. */
bool startsWith(string prefix) {
Trie* root = this;
for (auto c:prefix){
if (root->str[c-'a'] == nullptr) return false;
root = root->str[c-'a'];
}
return true;
}
};
根据身高重建队列 中等
class Solution {
public:
vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
auto cmp = [](vector<int>a, vector<int>b){
return (a[0] > b[0]) || (a[0] == b[0] && a[1] < b[1]);};
sort(people.begin(), people.end(), cmp);
vector<vector<int>> ans;
for(int i = 0; i < people.size(); i++)
//局部最优
ans.insert(ans.begin() + people[i][1], people[i]);
return ans;
}
};
字母异位词分组
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
unordered_map<string, vector<string>> map;
for (auto s:strs){
string temp(s);
sort(temp.begin(), temp.end());//这里排序是精髓
map[temp].push_back(s);
}
vector<vector<string>> res;
for (auto i:map){
vector<string> temp(i.second.begin(), i.second.end());
res.push_back(temp);
}
return res;
}
};
回文子串
class Solution {
int helper(string s, int l, int r){
int res = 0;
while (l>=0 && r<s.length() && s[l] == s[r]){
res++;
l--; r++;
}
return res;
}
public:
int countSubstrings(string s) {
if (s.empty()) return 0;
int res = 0;
for (int i=0; i<s.length(); i++){
res += helper(s, i, i);
res += helper(s, i, i+1);
}
return res;
}
};
前 K 个高频元素
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int, int> map;
for (auto n:nums)
map[n]++;
auto mycmp = [](pair<int,int> a, pair<int,int> b){return a.second > b.second;};
priority_queue<pair<int,int>, vector<pair<int,int>>, decltype(mycmp)> que(mycmp);
for (auto i:map){
if (que.empty() || k) {//在这里进行k的控制
que.push(i);
k--;
}
else{
if (i.second > que.top().second){
que.pop();
que.push(i);
}
}
}
vector<int> res;
while (!que.empty()){
auto temp = que.top();
que.pop();
res.push_back(temp.first);
}
return res;
}
};
打家劫舍 III
struct SubtreeStatus {
int selected;
int notSelected;
};
class Solution {
public:
SubtreeStatus dfs(TreeNode* root) {
if (root == NULL)
return {0, 0};
auto l = dfs(root->left);
auto r = dfs(root->right);
int selected = root->val + l.notSelected + r.notSelected;
int notSelected = max(l.selected, l.notSelected) + max(r.selected, r.notSelected);
return {selected, notSelected};
}
int rob(TreeNode* root) {
auto rootStatus = dfs(root);
return max(rootStatus.selected, rootStatus.notSelected);
}
};
完全平方数
转化为背包问题
class Solution {
public:
int numSquares(int n) {
vector<int> coins(sqrt(n)+1);
for (int i=1; i<coins.size(); i++)
coins[i] = i*i;
vector<int> dp(n+1, n+1); dp[0]=0;
for (int i=1; i<=n; i++){
for (int j=0; j<coins.size(); j++){
if (i >= coins[j])
dp[i] = min(dp[i], dp[i-coins[j]]+1);
}
}
return dp[n] > n ? -1 : dp[n];
}
};
路径总和 III
class Solution {
int res = 0;
void path(TreeNode* root, int sum){
if (root == nullptr) return;
sum -= root->val;
if (sum == 0)
res++;
path(root->left, sum);
path(root->right, sum);
}
public:
int pathSum(TreeNode* root, int sum) {
if (root == nullptr) return 0;
path(root, sum);
pathSum(root->left, sum);
pathSum(root->right, sum);
return res;
}
};
颜色分类
class Solution {
public:
void sortColors(vector<int>& nums) {
int p0 = 0, curr = 0;
int p2 = nums.size() - 1;
while (curr <= p2) {
if (nums[curr] == 0) {
swap(nums[curr++], nums[p0++]);
}
else if (nums[curr] == 2) {
swap(nums[curr], nums[p2--]);
}
else curr++;
}
}
};
电话号码的字母组合
class Solution {
unordered_map<char, string> map;
vector<string> res;
void backTrack(string digits, string& temp, int index){
if (digits.length() == index){
res.push_back(temp);
return;
}
for (int i=0; i<map[digits[index]].length(); i++){
temp += map[digits[index]][i];
backTrack(digits, temp, index+1);
temp.pop_back();
}
}
public:
vector<string> letterCombinations(string digits) {
map['2'] = "abc"; map['3'] = "def"; map['4'] = "ghi"; map['5'] = "jkl";
map['6'] = "mno"; map['7'] = "pqrs"; map['8'] = "tuv"; map['9'] = "wxyz";
if (digits.empty()) return {};
string temp("");
backTrack(digits, temp, 0);
return res;
}
};