class Solution {
public:intmySqrt(int x){int l =0, r = x;while(l < r){int mid =(longlong)l + r +1>>1;if(mid <= x/mid)l = mid;else r = mid -1;}return r;}};//这里为了防止溢出,加入long long
LeetCode 35. Search Insert Position
class Solution {
public:intsearchInsert(vector<int>& nums,int target){if(nums.empty()|| nums.back()< target)return nums.size();int l =0, r = nums.size()-1;while(l < r){int mid = l + r >>1;if(nums[mid]>= target)r = mid;else l = mid +1;}return r;}};
LeetCode 34. Find First and Last Position of Element in Sorted Array
class Solution {
public:
vector<int>searchRange(vector<int>& nums,int target){if(nums.empty())return{-1,-1};//找到左边界int l =0, r = nums.size()-1;while(l < r){int mid = l + r >>1;if(nums[mid]>= target)r = mid;else l = mid +1;}if(nums[r]!= target)return{-1,-1};int start = r;//找到右边界
l =0, r = nums.size()-1;while(l < r){int mid = l + r +1>>1;if(nums[mid]<= target)l = mid;else r = mid -1;}int end = r;return{start, end};}};
LeetCode 74. Search a 2D Matrix
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix,int target){//判断边界条件if(matrix.empty()|| matrix[0].empty())return false;//用二分去查找,这里有一个换算关系,最后还要判断是不大于int n = matrix.size(), m = matrix[0].size();int l =0, r = n * m -1;while(l < r){int mid = l + r >>1;if(matrix[mid / m][mid % m]>= target)r = mid;else l = mid +1;}if(matrix[r / m][r % m]!= target)return false;return true;}};
LeetCode 153. Find Minimum in Rotated Sorted Array
class Solution {
public:intfindMin(vector<int>& nums){int l =0, r = nums.size()-1;//这里是直接二分,找到分界点while(l < r){int mid = l + r >>1;if(nums[mid]<= nums.back())r = mid;else l = mid +1;}return nums[r];}};
LeetCode 33. Search in Rotated Sorted Array
class Solution {
public:intsearch(vector<int>& nums,int target){//首先这里是边界条件if(nums.empty())return-1;//通过分段的性质,找到最小的分解线int l =0, r = nums.size()-1;while(l < r){int mid = l + r >>1;if(nums[mid]<= nums.back())r = mid;else l = mid +1;}//这里判断目标到底是在哪里if(target <= nums.back()) r = nums.size()-1;else l =0, r --;//再次进行二分即可找到大于等于targetwhile(l < r){int mid = l + r >>1;if(nums[mid]>= target) r = mid;else l = mid +1;}if(nums[l]== target)return l;return-1;}};
LeetCode 278. First Bad Version
// Forward declaration of isBadVersion API.
bool isBadVersion(int version);
class Solution {
public:intfirstBadVersion(int n){int l =1, r = n;while(l < r){int mid =(longlong)l + r >>1;if(isBadVersion(mid)) r = mid;else l = mid +1;}return r;}};
LeetCode 162. Find Peak Element
class Solution {
public:intfindPeakElement(vector<int>& nums){//这题写法简单,但是思路不明白int l =0, r = nums.size()-1;while(l < r){int mid = l + r >>1;if(nums[mid]> nums[mid+1]) r = mid;else l = mid +1;}return r;}};
LeetCode 287. Find the Duplicate Number
class Solution {
public:intfindDuplicate(vector<int>& nums){int l =1, r = nums.size()-1;//这道题很特殊,利用抽屉,然后可以分成两部分,必然有一部分是多的while(l < r){int mid = l + r >>1;int cnt =0;for(auto x : nums)if(x >=1&& x <= mid)
cnt++;if(cnt > mid -1+1)r = mid;else l = mid +1;}return r;}};
LeetCode 275. H-Index II
class Solution {
public:inthIndex(vector<int>& nums){int l =0, r = nums.size();while(l < r){int mid = l + r +1>>1;if(nums[nums.size()- mid]>= mid) l = mid;else r = mid -1;}return r;}};
链表专题
LeetCode 19. Remove Nth Node From End of List
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode*removeNthFromEnd(ListNode* head,int n){//因为头结点可能会改变,所有建立了一个虚拟结点,不需要特判auto dummy = new ListNode(-1);
dummy->next = head;//建立了一个快慢指针auto first = dummy, second = dummy;//快指针先走n步while(n--) first = first->next;//快慢指针一块走,知道快指针走到了空指针了while(first->next){
first = first->next;
second = second->next;}//建立连接关系
second->next = second->next->next;return dummy->next;}};
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode*sortList(ListNode* head){int n =0;for(ListNode *p = head; p; p = p->next) n ++;
ListNode *dummy = new ListNode(-1);
dummy->next = head;for(int i =1; i < n; i *=2){
ListNode *begin = dummy;for(int j =0; j + i < n; j += i *2){
ListNode *first = begin->next,*second = first;for(int k =0; k < i; k ++)
second = second->next;int f =0, s =0;while(f < i && s < i && second)if(first->val < second->val){
begin = begin->next = first;
first = first->next;
f ++;}else{
begin = begin->next = second;
second = second->next;
s ++;}while(f < i){
begin = begin->next = first;
first = first->next;
f ++;}while(s < i && second){
begin = begin->next = second;
second = second->next;
s ++;}
begin->next = second;}}return dummy->next;}};
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*///方法一// 1.两个根节点的值要想相等// 2.左边的左子树和右边的右子树对称// 3.左边的右子树和右边的左子树对称// class Solution {// public:// bool isSymmetric(TreeNode* root) {// if(!root) return true;// return dfs(root->left, root->right);// }// bool dfs(TreeNode* p, TreeNode* q)// {// if(!p || !q) return !p && !q;// return p->val == q->val && dfs(p->left, q->right) && dfs(p->right, q->left);// }// };//方法二//左边:左中右遍历,右边:右中左进行遍历//这种方法就是用迭代的方式进行的
class Solution {
public:
bool isSymmetric(TreeNode* root){if(!root)return true;
stack<TreeNode*>left, right;auto l = root->left, r = root->right;while(l || r || left.size()|| right.size()){while(l && r){
left.push(l), l = l->left;
right.push(r), r = r->right;}if(l || r)return false;
l = left.top(), left.pop();
r = right.top(), right.pop();if(l->val != r->val)return false;
l = l->right, r = r->left;}return true;}};
LeetCode 94. Binary Tree Inorder Traversal
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/// 1.将整棵树的最左边一条链压入栈中// 2.每次取出栈顶元素,如果它有右子树,则将右子树压入栈中//这种是一种迭代的方式,后面很多题都会用到
class Solution {
public:
vector<int>inorderTraversal(TreeNode* root){
vector<int> res;
stack<TreeNode*> stk;auto p = root;while(p || stk.size()){while(p){
stk.push(p);
p = p->left;}
p = stk.top();
stk.pop();
res.push_back(p->val);
p = p->right;}return res;}};
LeetCode 105. Construct Binary Tree from Preorder and Inorder Traversal
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
unordered_map<int,int> pos;
TreeNode*buildTree(vector<int>& preorder, vector<int>& inorder){int n = preorder.size();for(int i =0; i < n; i++)pos[inorder[i]]= i;returndfs(preorder, inorder,0, n-1,0, n-1);}
TreeNode*dfs(vector<int>& preorder, vector<int>& inorder,int pl,int pr,int il,int ir){if(pl > pr)returnNULL;int val = preorder[pl];int k = pos[val];int len = k - il;auto root = new TreeNode(val);
root->left =dfs(preorder, inorder, pl +1, pl + len, il, k-1);
root->right =dfs(preorder, inorder, pl + len +1, pr, k+1, il);return root;}};
LeetCode 102. Binary Tree Level Order Traversal
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*///因为是层序遍历,这里直接用BFS
class Solution {
public:
vector<vector<int>>levelOrder(TreeNode* root){
vector<vector<int>> res;if(!root)return res;//使用队列进行bfs,也可以用数组去实现
queue<TreeNode*> q;
q.push(root);while(q.size()){//队列的长度就是需要输出的长度int len = q.size();
vector<int> level;//一方面需要把数值加到队列中,一方面不要忘记了扩展队列for(int i =0; i < len; i++){auto t = q.front();
q.pop();
level.push_back(t->val);if(t->left) q.push(t->left);if(t->right) q.push(t->right);}
res.push_back(level);}return res;}};
LeetCode 236. Lowest Common Ancestor of a Binary Tree
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*///这题不是很明白//如果以root为根的子树中包含p和q,则返回他们最近的公共祖先//如果只包含p,则返回p//如果只包含q,则返回q//如果都不包含,则返回NULL
class Solution {
public:
TreeNode*lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q){if(!root || root == p || root == q)return root;auto left =lowestCommonAncestor(root->left, p, q);auto right =lowestCommonAncestor(root->right, p, q);if(!left)return right;if(!right)return left;return root;}};
LeetCode 297. Serialize and Deserialize Binary Tree
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Codec {
public:// Encodes a tree to a single string.
string serialize(TreeNode* root){
string res;dfs1(root, res);return res;}voiddfs1(TreeNode* root, string& res){if(!root){
res +="#,";return;}
res +=to_string(root->val)+',';dfs1(root->left, res);dfs1(root->right, res);}// Decodes your encoded data to tree.
TreeNode*deserialize(string data){int u =0;returndfs2(data, u);}
TreeNode*dfs2(string &data,int&u){if(data[u]=='#'){
u +=2;returnNULL;}int t =0;
bool is_minus = false;while(data[u]!=','){if(data[u]=='-') is_minus = true;else t = t *10+ data[u]-'0';
u ++;}
u ++;if(is_minus) t =-t;auto root = new TreeNode(t);
root->left =dfs2(data, u);
root->right =dfs2(data, u);return root;}};// Your Codec object will be instantiated and called as such:// Codec codec;// codec.deserialize(codec.serialize(root));
LeetCode 543. Diameter of Binary Tree
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*///枚举所有的最高点//递归时需要计算,从当前结点往下走,深层的最大值
class Solution {
public:int ans =0;intdiameterOfBinaryTree(TreeNode* root){dfs(root);return ans;}intdfs(TreeNode *root){if(!root)return0;auto left =dfs(root->left);auto right =dfs(root->right);
ans =max(ans, left + right);returnmax(left+1, right+1);}};
LeetCode 124. Binary Tree Maximum Path Sum
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*///这题和求树的最大直径是很相似的,dfs返回的不是答案,而是深度
class Solution {
public:int ans = INT_MIN;intmaxPathSum(TreeNode* root){dfs(root);return ans;}intdfs(TreeNode *root){if(!root)return0;auto left =dfs(root->left);auto right =dfs(root->right);
ans =max(ans, left + root->val + right);returnmax(0, root->val +max(left, right));}};
LeetCode 173. Binary Search Tree Iterator
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*///迭代的方式
class BSTIterator {
public:
stack<TreeNode*> stk;BSTIterator(TreeNode* root){while(root){
stk.push(root);
root = root->left;}}/** @return the next smallest number */intnext(){auto p = stk.top();
stk.pop();int res = p->val;
p = p->right;while(p){
stk.push(p);
p = p->left;}return res;}/** @return whether we have a next smallest number */
bool hasNext(){return!stk.empty();}};/**
* Your BSTIterator object will be instantiated and called as such:
* BSTIterator* obj = new BSTIterator(root);
* int param_1 = obj->next();
* bool param_2 = obj->hasNext();
*/
字符串处理
LeetCode 38. Count and Say
class Solution {
public://模拟题
string countAndSay(int n){
string s ="1";for(int i =0; i < n-1; i++){
string ns;for(int j =0; j < s.size(); j++){//常用技巧int k = j;while(k < s.size()&& s[k]== s[j])k++;
ns +=to_string(k - j)+ s[j];
j = k -1;}
s = ns;}return s;}};
class Solution {
public:
string reverseWords(string s){//首先翻转每一个单词,然后翻转整个句子就能达到这样的效果int k =0;for(int i =0; i < s.size(); i++){while(i < s.size()&& s[i]==' ')i++;if(i == s.size())break;int j = i;while(j < s.size()&& s[j]!=' ')j++;reverse(s.begin()+ i, s.begin()+ j);if(k) s[k++]=' ';while(i < j)s[k++]= s[i++];}
s.erase(s.begin()+ k, s.end());reverse(s.begin(), s.end());return s;}};
LeetCode 165. Compare Version Numbers
class Solution {
public:intcompareVersion(string s1, string s2){//这里使用双指针进行比较int i =0, j =0;while(i < s1.size()|| j < s2.size()){int x = i, y = j;//x, y分别代表每一段的值,这里用到了常用的编码方式,移动指针while(x < s1.size()&& s1[x]!='.') x++;while(y < s2.size()&& s2[y]!='.') y++;//将字符转化为数字int a = i == x ?0:atoi(s1.substr(i, x - i).c_str());int b = j == y ?0:atoi(s2.substr(j, y - j).c_str());if(a > b)return1;if(a < b)return-1;//移动到下一段
i = x +1, j = y +1;}return0;}};
LeetCode 929. Unique Email Addresses
class Solution {
public:intnumUniqueEmails(vector<string>& emails){//建立一个hash表,存储不一样的email
unordered_set<string> hash;//遍历所有的email,去伪存真for(auto email : emails){//找到@的位置,这里用find函数int at = email.find("@");
string name;//遍历每一个字母for(auto c : email.substr(0, at)){//+截断if(c =='+'){break;}elseif(c !='.'){
name += c;}}//后面一段
string domain = email.substr(at+1);//把处理好的email,存入hash,读取hash大小即可
hash.insert(name +'@'+ domain);}return hash.size();}};
LeetCode 5. Longest Palindromic Substring
class Solution {
public:
string longestPalindrome(string s){
string res;//枚举每一个起点,然后向两边扩展for(int i =0; i < s.size(); i++){//奇数的情况for(int j = i, k = i; j >=0&& k < s.size()&& s[j]== s[k]; j--, k++)if(res.size()< k - j +1)
res = s.substr(j, k - j +1);//偶数的情况for(int j = i, k = i +1; j >=0&& k < s.size()&& s[j]== s[k]; j--, k++)if(res.size()< k - j +1)
res = s.substr(j, k - j +1);}return res;}};
LeetCode 6. ZigZag Conversion
class Solution {
public:
string convert(string s,int n){//模拟题if(n ==1)return s;
string res;for(int i =0; i < n; i++){if(!i || i == n -1){for(int j = i; j < s.size(); j +=2*(n -1)) res += s[j];}else{for(int j = i, k =2*(n -1)- i; j < s.size()|| k < s.size(); j +=2*(n -1), k +=2*(n -1)){if(j < s.size()) res += s[j];if(k < s.size()) res += s[k];}}}return res;}};
LeetCode 3. Longest Substring Without Repeating Characters
class Solution {
public:intlengthOfLongestSubstring(string s){//首先可以想到用hash来判断是不是重复数字//之后先暴力枚举,发现双指针能优化
unordered_map<char,int> hash;int res =0;for(int i =0, j =0; i < s.size(); i++){
hash[s[i]]++;while(hash[s[i]]>1)hash[s[j++]]--;
res =max(res, i - j +1);}return res;}};
LeetCode 208. Implement Trie (Prefix Tree)
class Trie {
public://Trie对应每一个节点的结构体struct Node
{
bool is_end;
Node *son[26];Node(){
is_end = false;for(int i =0; i <26; i++) son[i]=NULL;}}*root;/** Initialize your data structure here. */Trie(){
root = new Node();}//如果为空,则插入,到了结尾处则标记为true/** Inserts a word into the trie. */voidinsert(string word){auto p = root;for(auto c : word){int u = c -'a';if(p->son[u]==NULL)p->son[u]= new Node();
p = p->son[u];}
p->is_end = true;}//查找有没有,中间没有直接return,之后看看结尾标记了/** Returns if the word is in the trie. */
bool search(string word){auto p = root;for(auto c : word){int u = c -'a';if(p->son[u]==NULL)return false;
p = p->son[u];}return p->is_end;}//这个是只要存在就好,不是结尾也是ok的/** Returns if there is any word in the trie that starts with the given prefix. */
bool startsWith(string prefix){auto p = root;for(auto c : prefix){int u = c -'a';if(p->son[u]==NULL)return false;
p = p->son[u];}return true;}};/**
* Your Trie object will be instantiated and called as such:
* Trie* obj = new Trie();
* obj->insert(word);
* bool param_2 = obj->search(word);
* bool param_3 = obj->startsWith(prefix);
*/
LeetCode 273. Integer to English Words
class Solution {
public:
string small[20]={"Zero","One","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten","Eleven","Twelve","Thirteen","Fourteen","Fifteen","Sixteen","Seventeen","Eighteen","Nineteen"};
string decade[10]={"","","Twenty","Thirty","Forty","Fifty","Sixty","Seventy","Eighty","Ninety"};
string big[4]={"Billion","Million","Thousand",""};//这里把每一个分成一段一段的,3个一组
string numberToWords(int num){//特判为0if(!num)return small[0];
string res;for(int i =1000000000, j =0; i >0; i /=1000, j++){if(num >= i){
res +=get_part(num / i)+ big[j]+' ';
num %= i;}}while(res.back()==' ') res.pop_back();return res;}
string get_part(int num){
string res;if(num >=100){
res += small[num /100]+" Hundred ";
num %=100;}if(!num)return res;if(num >=20){
res += decade[num /10]+' ';
num %=10;}if(!num)return res;
res += small[num]+' ';return res;}};
DFS+回溯
LeetCode 17. Letter Combinations of a Phone Number
class Solution {
public:// state = {""}// for 每个数字// for c = 当前数字的所有备选字母// for s = state中的所有字符串// s += c
string chars[8]={"abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
vector<string>letterCombinations(string digits){if(digits.empty())return vector<string>();
vector<string>state(1,"");for(auto u : digits){
vector<string> now;for(auto c : chars[u -'2'])for(auto s : state)
now.push_back(s + c);
state = now;}return state;}};
LeetCode 79. Word Search
class Solution {
public:int n, m;//这是四个方向int dx[4]={-1,0,1,0};int dy[4]={0,1,0,-1};
bool exist(vector<vector<char>>& board, string word){if(board.empty()|| board[0].empty())return false;
n = board.size(), m = board[0].size();//对面板上的每一个点都枚举for(int i =0; i < n; i++)for(int j =0; j < m; j++)if(dfs(board, i, j, word,0))return true;return false;}
bool dfs(vector<vector<char>>& board,int x,int y, string& word,int u){if(board[x][y]!= word[u])return false;if(u == word.size()-1)return true;//这里有回溯,要恢复现场
board[x][y]='.';for(int i =0; i <4; i++){int a = x + dx[i];int b = y + dy[i];if(a >=0&& a < n && b >=0&& b < m)if(dfs(board, a, b, word, u+1))return true;}
board[x][y]= word[u];return false;}};
LeetCode 46. Permutations
class Solution {
public:int n;//用来标记某个数字是否用了
vector<bool> st;//存储最终的答案
vector<vector<int>> ans;//存储当前的答案
vector<int> path;
vector<vector<int>>permute(vector<int>& nums){//初始化
n = nums.size();
st = vector<bool>(n);//深搜+回溯dfs(nums,0);return ans;}voiddfs(vector<int>& nums,int u){//达到了终止条件if(u == n){
ans.push_back(path);return;}for(int i =0; i < n; i++){if(!st[i]){//标记现场
st[i]= true;
path.push_back(nums[i]);dfs(nums, u +1);//恢复现场
path.pop_back();
st[i]= false;}}}};
LeetCode 47. Permutations II
class Solution {
public://这里用全局,值引用,这样就不用重复赋值int n;//答案
vector<vector<int>> ans;//当前枚举的路径
vector<int> path;//标记数组
vector<bool> st;
vector<vector<int>>permuteUnique(vector<int>& nums){//初始化
n = nums.size();
st = vector<bool>(n);
path = vector<int>(n);//这里通过排序,使得相同的数字排在一块了,对于相同的数字人为规定一个顺序sort(nums.begin(), nums.end());dfs(nums,0,0);return ans;}voiddfs(vector<int>& nums,int u,int start){//终止条件if(u == n){
ans.push_back(path);return;}//是否是相同的数字,如果是则接着找for(int i = start; i < n; i++){if(!st[i]){
st[i]= true;
path[i]= nums[u];dfs(nums, u +1, u +1< n && nums[u+1]== nums[u]? i :0);
st[i]= false;}}}};
LeetCode 78. Subsets
class Solution {
public:
vector<vector<int>>subsets(vector<int>& nums){//这里存答案
vector<vector<int>> res;//每个数字有两种状态,所以一共有1 << nums.size()中状态,然后填充答案即可for(int i =0; i <1<< nums.size(); i++){
vector<int> now;for(int j =0; j < nums.size(); j++){if(i >> j &1)
now.push_back(nums[j]);}
res.push_back(now);}return res;}};
LeetCode 90. Subsets II
class Solution {
public://常规操作,变量
vector<vector<int>> ans;
vector<int> path;
vector<vector<int>>subsetsWithDup(vector<int>& nums){//排个序,这样相同的数字会排在一块sort(nums.begin(), nums.end());dfs(nums,0);return ans;}voiddfs(vector<int>& nums,int u){//终止条件if(u == nums.size()){
ans.push_back(path);return;}//这里不一样了,有多少个重复的数字int k =0;while(u + k < nums.size()&& nums[u + k]== nums[u])k++;for(int i =0; i <= k; i ++){dfs(nums, u + k);
path.push_back(nums[u]);}for(int i =0; i <= k; i++)path.pop_back();}};
LeetCode 216. Combination Sum III
class Solution {
public:
vector<vector<int>> ans;
vector<int> path;
vector<vector<int>>combinationSum3(int k,int n){dfs(k,1, n);return ans;}voiddfs(int k,int start,int n){if(!k){if(!n) ans.push_back(path);return;}for(int i = start; i <=10- k; i++){
path.push_back(i);dfs(k -1, i +1, n - i);
path.pop_back();}}};
LeetCode 52. N-Queens II
class Solution {
public:int ans;
vector<bool> row, col, diag, anti_diag;inttotalNQueens(int n){
row = col = vector<bool>(n, false);
diag = anti_diag = vector<bool>(2* n, false);
ans =0;dfs(0,0,0, n);return ans;}voiddfs(int x,int y,int s,int n){if(y == n) x ++, y =0;if(x == n){if(s == n)++ ans;return;}dfs(x, y +1, s, n);if(!row[x]&&!col[y]&&!diag[x + y]&&!anti_diag[n -1- x + y]){
row[x]= col[y]= diag[x + y]= anti_diag[n -1- x + y]= true;dfs(x, y +1, s +1, n);
row[x]= col[y]= diag[x + y]= anti_diag[n -1- x + y]= false;}}};
LeetCode 37. Sudoku Solver
class Solution {
public://不明觉厉
bool row[9][9]={0}, col[9][9]={0}, cell[3][3][9]={0};voidsolveSudoku(vector<vector<char>>& board){for(int i =0; i <9; i++){for(int j =0; j <9; j++){char c = board[i][j];if(c !='.'){int t = c -'1';
row[i][t]= col[j][t]= cell[i /3][j /3][t]= true;}}}dfs(board,0,0);}
bool dfs(vector<vector<char>>& board,int x,int y){if(y ==9) x++, y =0;if(x ==9)return true;if(board[x][y]!='.')returndfs(board, x, y+1);for(int i =0; i <9; i++){if(!row[x][i]&&!col[y][i]&&!cell[x /3][y /3][i]){
board[x][y]='1'+ i;
row[x][i]= col[y][i]= cell[x /3][y /3][i]= true;if(dfs(board, x, y +1))return true;
row[x][i]= col[y][i]= cell[x /3][y /3][i]= false;
board[x][y]='.';}}return false;}};
LeetCode 473. Matchsticks to Square
class Solution {
public:// 这题是裁剪的经典题目:// 首先是依次构造正方的每条边// 剪枝:// 1.从大到小枚举所有边// 2.每条边内部的木棒长度规定成从大到小// 3.如果当前木棒拼接失败,则跳过接下来所有长度相同的木棒// 4.如果当前木棒拼接失败,且是当前边的第一个,则直接剪掉当前分支// 5.如果当前木棒拼接失败,且是当前边的最后一个,则直接剪掉当前分支
vector<bool> st;
bool makesquare(vector<int>& nums){int sum =0;for(auto u : nums) sum += u;if(!sum || sum %4)return false;sort(nums.begin(), nums.end());reverse(nums.begin(), nums.end());
st = vector<bool>(nums.size());returndfs(nums,0,0, sum /4);}
bool dfs(vector<int>& nums,int u,int cur,int length){if(cur == length)u++, cur =0;if(u ==4)return true;for(int i =0; i < nums.size(); i++){if(!st[i]&& cur + nums[i]<= length){
st[i]= true;if(dfs(nums, u, cur + nums[i], length))return true;
st[i]= false;if(!cur)return false;if(cur + nums[i]== length)return false;while(i +1< nums.size()&& nums[i]== nums[i+1]) i++;}}return false;}};
滑动窗口、双指针与单调队列/栈
LeetCode 167. Two Sum II - Input array is sorted
class Solution {
public://首先是暴力枚举->然后观察有无单调性->进行枚举
vector<int>twoSum(vector<int>& numbers,int target){for(int j =0, i = numbers.size()-1; j < numbers.size(); j++){while(i-1> j && numbers[i -1]+ numbers[j]>= target)i--;if(numbers[i]+numbers[j]== target)return{j +1, i +1};}return{-1,-1};}};
LeetCode 88. Merge Sorted Array
class Solution {
public:voidmerge(vector<int>& nums1,int m, vector<int>& nums2,int n){int i = m -1, j = n-1, k = m + n -1;while(i >=0&& j >=0){if(nums1[i]> nums2[j]) nums1[k--]= nums1[i--];else nums1[k--]= nums2[j--];}while(j >=0)nums1[k--]= nums2[j--];}};
LeetCode 26. Remove Duplicates from Sorted Array
class Solution {
public:intremoveDuplicates(vector<int>& nums){if(nums.empty())return0;//使用双指针int k =1;for(int j =1; j < nums.size(); j++)if(nums[j]!= nums[j-1])
nums[k++]= nums[j];return k;}};
LeetCode 76. Minimum Window Substring
class Solution {
public:
string minWindow(string s, string t){
unordered_map<char,int> hash;int cnt =0;for(auto c : t){if(!hash[c]) cnt ++;
hash[c]++;}
string res ="";for(int i =0, j =0, c =0; i < s.size(); i ++){if(hash[s[i]]==1) c ++;
hash[s[i]]--;while(c == cnt && hash[s[j]]<0) hash[s[j ++]]++;if(c == cnt){if(res.empty()|| res.size()> i - j +1) res = s.substr(j, i - j +1);}}return res;}};
LeetCode 32. Longest Valid Parentheses
class Solution {
public:// 括号序列合法 <=> 所有前缀和 >= 0, 且总和等于0// )()())// start 当前枚举的这一段开头// cnt 前缀和// ( = 1, ) = -1// 1.cnt <= 0, start = i + 1, cnt = 0;// 2.cnt > 0, 继续做// 3.cnt == 0, [start, i]是一段合法的序列intwork(string s){int res =0;for(int i =0, start =0, cnt =0; i < s.size(); i++){if(s[i]=='(') cnt++;else{
cnt--;if(cnt <0) start = i +1, cnt =0;elseif(!cnt) res =max(res, i - start+1);}}return res;}intlongestValidParentheses(string s){int res =work(s);reverse(s.begin(), s.end());for(auto&c : s) c ^=1;returnmax(res,work(s));}};
LeetCode 155. Min Stack
// MinStack minStack = new MinStack();// minStack.push(-2);// minStack.push(0);// minStack.push(-3);// minStack.getMin(); --> Returns -3.// minStack.pop();// minStack.top(); --> Returns 0.// minStack.getMin(); --> Returns -2.
class MinStack {
public://首先是定义一个栈和一个最小栈
stack<int> stk, stk_min;/** initialize your data structure here. */MinStack(){}//栈里面就随便加,最小栈要比较下,最小栈存的是当前栈中最小的数值//如果比较小,则放入栈中,否则则不放入voidpush(int x){
stk.push(x);if(stk_min.empty()) stk_min.push(x);else stk_min.push(min(x, stk_min.top()));}//弹出的话,就是一起弹处来就可以了voidpop(){
stk.pop();
stk_min.pop();}//栈顶元素inttop(){return stk.top();}//栈顶元素,这里要注意,stack和vector函数有点像,但是不一样呢intgetMin(){return stk_min.top();}};/**
* Your MinStack object will be instantiated and called as such:
* MinStack* obj = new MinStack();
* obj->push(x);
* obj->pop();
* int param_3 = obj->top();
* int param_4 = obj->getMin();
*/
LeetCode 42. Trapping Rain Water
class Solution {
public:inttrap(vector<int>& height){int res =0;
stack<int> stk;for(int i =0; i < height.size(); i ++){int last =0;while(stk.size()&& height[stk.top()]<= height[i]){int t = stk.top(); stk.pop();
res +=(i - t -1)*(height[t]- last);
last = height[t];}if(stk.size()) res +=(i - stk.top()-1)*(height[i]- last);
stk.push(i);}return res;}};
LeetCode 84. Largest Rectangle in Histogram
class Solution {
public:/*
单调栈:查找每个数左侧第一个比它小的数
单调队列:滑动窗口中的最值
如何枚举处所有的情况呢?
枚举所有柱形的上边界,作为整个矩形的上边界
然后求出左右边界:
1.找出左边离它最近的,比它小的柱形
1.找出右边离它最近的,比它小的柱形
*///首先来说是确认上边界,然后找到左右的边界intlargestRectangleArea(vector<int>& heights){//高度int n = heights.size();//定义两个左右的边界
vector<int>left(n),right(n);//这里是利用单调栈的性质,是一个升序
stack<int> stk;for(int i =0; i < n; i++){while(stk.size()&& heights[stk.top()]>= heights[i])stk.pop();if(stk.empty()) left[i]=-1;else left[i]= stk.top();
stk.push(i);}while(stk.size()) stk.pop();//同理,找到右边界for(int i = n -1; i >=0; i--){while(stk.size()&& heights[stk.top()]>= heights[i]) stk.pop();if(stk.empty()) right[i]= n;else right[i]= stk.top();
stk.push(i);}int res =0;for(int i =0; i < n; i++) res =max(res, heights[i]*(right[i]- left[i]-1));return res;}};
LeetCode 239. Sliding Window Maximum
class Solution {
public:
vector<int>maxSlidingWindow(vector<int>& nums,int k){
vector<int> res;
deque<int> q;for(int i =0; i < nums.size(); i ++){if(q.size()&& i - k >= q.front()) q.pop_front();while(q.size()&& nums[q.back()]<= nums[i]) q.pop_back();
q.push_back(i);if(i >= k -1) res.push_back(nums[q.front()]);}return res;}};
LeetCode 918. Maximum Sum Circular Subarray
/*
单调栈:查找每个数左侧第一个比它小的数
单调队列:滑动窗口中的最值
*/
class Solution {
public:intmaxSubarraySumCircular(vector<int>& A){int n = A.size();for(int i =0; i < n; i++) A.push_back(A[i]);//因为是个环,所以展开成2×n,这样的话所有的情况都可以枚举的到
vector<int>sum(n *2+1);//然后使用前缀和for(int i =1; i <= n *2; i++) sum[i]= sum[i-1]+ A[i-1];int res = INT_MIN;//用队列求最值
deque<int> q;
q.push_back(0);for(int i =1; i <= n *2; i++){if(q.size()&& i - n > q.front()) q.pop_front();if(q.size()) res =max(res, sum[i]- sum[q.front()]);while(q.size()&& sum[q.back()]>= sum[i]) q.pop_back();
q.push_back(i);}return res;}};
基本数据结构
LeetCode 1. Two Sum
class Solution {
public://枚举所有的,如果哈希表中存在则返回
vector<int>twoSum(vector<int>& nums,int target){
unordered_map<int,int> hash;for(int i =0; i < nums.size(); i++){if(hash.count(target - nums[i]))return{hash[target - nums[i]], i};
hash[nums[i]]= i;}return{-1,-1};}};
LeetCode 187. Repeated DNA Sequences
class Solution {
public:
vector<string>findRepeatedDnaSequences(string s){
unordered_map<string,int> hash;//插入一个字符串//统计字符串出现的次数
vector<string> res;for(int i =0; i < s.size(); i++){//这里substr的第二个参数是长度,要注意
string str = s.substr(i,10);
hash[str]++;//当然一个字符串可能出现2次以上,我们只记录一次if(hash[str]==2) res.push_back(str);}return res;}};
LeetCode 706. Design HashMap
class MyHashMap {
public:/** Initialize your data structure here. */conststaticint N =20011;
vector<list<pair<int,int>>> hash;MyHashMap(){
hash = vector<list<pair<int,int>>>(N);}
list<pair<int,int>>::iterator find(int key){int t = key % N;auto it = hash[t].begin();for(; it != hash[t].end(); it ++)if(it->first == key)break;return it;}/** value will always be non-negative. */voidput(int key,int value){int t = key % N;auto it =find(key);if(it == hash[t].end())
hash[t].push_back(make_pair(key, value));else
it->second = value;}/** Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key */intget(int key){auto it =find(key);if(it == hash[key % N].end())return-1;return it->second;}/** Removes the mapping of the specified value key if this map contains a mapping for the key */voidremove(int key){int t = key % N;auto it =find(key);if(it != hash[t].end())
hash[t].erase(it);}};/**
* Your MyHashMap object will be instantiated and called as such:
* MyHashMap obj = new MyHashMap();
* obj.put(key,value);
* int param_2 = obj.get(key);
* obj.remove(key);
*/
LeetCode 652. Find Duplicate Subtrees
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:int cnt =0;
unordered_map<string,int> hash;
unordered_map<int,int> count;
vector<TreeNode*> ans;//只有前序中序和后序并不能唯一确定一颗树,但是把空节点算上的话就可以
string dfs(TreeNode* root){if(!root)returnto_string(hash["#"]);//把树进行编码,同时查找 auto left =dfs(root->left);auto right =dfs(root->right);
string tree =to_string(root->val)+','+ left +','+ right;if(!hash.count(tree)) hash[tree]=++ cnt;int t = hash[tree];
count[t]++;if(count[t]==2) ans.push_back(root);returnto_string(t);}
vector<TreeNode*>findDuplicateSubtrees(TreeNode* root){
hash["#"]=++cnt;dfs(root);return ans;}};
LeetCode 560. Subarray Sum Equals K
class Solution {
public://这里用到了前缀和和hash表进行查找intsubarraySum(vector<int>& nums,int k){
unordered_map<int,int> hash;
hash[0]=1;int res =0;for(int i =0, sum =0; i < nums.size(); i++){
sum += nums[i];
res += hash[sum - k];
hash[sum]++;}return res;}};
LeetCode 547. Friend Circles
class Solution {
public:/*
1.合并集合
2.判断两个点是否在同一个集合中
并查集中常用的优化方法:路径压缩,按秩合并
*/
vector<int> p;intfind(int x){if(p[x]!= x) p[x]=find(p[x]);return p[x];}intfindCircleNum(vector<vector<int>>& M){int n = M.size();for(int i =0; i < n; i++) p.push_back(i);int res = n;for(int i =0; i < n; i++){for(int j =0; j < i; j++){if(M[i][j]==0)continue;if(find(i)!=find(j)){
p[find(i)]=find(j);
res--;}}}return res;}};
LeetCode 684. Redundant Connection
class Solution {
public://查并集,如果新加入的两个点的父节点是同一个,说明他们已经是连接了,再加入就是多余的边
vector<int> p;intfind(int x){if(p[x]!= x) p[x]=find(p[x]);return p[x];}
vector<int>findRedundantConnection(vector<vector<int>>& edges){int n = edges.size();for(int i =0; i <= n; i++) p.push_back(i);for(auto e : edges){int a = e[0], b = e[1];if(find(a)==find(b))return{a, b};
p[find(a)]=find(b);}return{-1,-1};}};
LeetCode 692. Top K Frequent Words
class Solution {
public:
vector<string>topKFrequent(vector<string>& words,int k){//使用哈希表+最小堆
unordered_map<string,int> hash;typedef pair<int, string> PIS;
priority_queue<PIS> heap;for(auto word : words) hash[word]++;for(auto item : hash){//一直放到,多了的话把最差的踢出来
PIS t(-item.second, item.first);
heap.push(t);if(heap.size()> k) heap.pop();}//取出答案
vector<string>res(k);for(int i = k -1; i >=0; i--){
res[i]= heap.top().second;
heap.pop();}return res;}};
LeetCode 295. Find Median from Data Stream
class MedianFinder {
public://这里用到对顶堆//如果x大于等于下面的根节点,将其插入上面;//如果x小于下面的根节点,将x插入下面
priority_queue<int, vector<int>, greater<int>> up;
priority_queue<int> down;/** initialize your data structure here. */MedianFinder(){}voidaddNum(int num){if(down.empty()|| num >= down.top()) up.push(num);else{
down.push(num);
up.push(down.top());
down.pop();}if(up.size()> down.size()+1){
down.push(up.top());
up.pop();}}doublefindMedian(){if(down.size()+ up.size()&1)return up.top();elsereturn(down.top()+ up.top())/2.0;}};/**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder* obj = new MedianFinder();
* obj->addNum(num);
* double param_2 = obj->findMedian();
*/
LeetCode 352. Data Stream as Disjoint Intervals
class SummaryRanges {
public:
map<int,int> L, R;/** Initialize your data structure here. */SummaryRanges(){}voidaddNum(int x){if(L.size()){auto it = L.lower_bound(x);if(it != L.end()&& it->second <= x)return;}int left = L.count(x -1), right = R.count(x +1);if(left & right){
R[L[x -1]]= R[x +1];
L[R[x +1]]= L[x -1];
L.erase(x -1), R.erase(x +1);}elseif(left){
R[L[x -1]]= x;
L[x]= L[x -1];
L.erase(x -1);}elseif(right){
L[R[x +1]]= x;
R[x]= R[x +1];
R.erase(x +1);}else{
R[x]= L[x]= x;}}
vector<vector<int>>getIntervals(){
vector<vector<int>> res;for(auto item : R) res.push_back({item.first, item.second});return res;}};/**
* Your SummaryRanges object will be instantiated and called as such:
* SummaryRanges* obj = new SummaryRanges();
* obj->addNum(val);
* vector<vector<int>> param_2 = obj->getIntervals();
*/
动态规划
LeetCode 53. Maximum Subarray
class Solution {
public://求出所有子段的和的最大值//枚举所有的起点和终点intmaxSubArray(vector<int>& nums){int res = INT_MIN, last =0;for(int i =0; i < nums.size(); i++){int now =max(last,0)+ nums[i];
res =max(res, now);
last = now;}return res;}};
LeetCode 120. Triangle
class Solution {
public:intminimumTotal(vector<vector<int>>& nums){int n = nums.size();
vector<vector<longlong>>f(2, vector<longlong>(n));
f[0][0]= nums[0][0];for(int i =1; i < n; i++)for(int j =0; j <= i; j++){
f[i &1][j]= INT_MAX;if(j >0) f[i &1][j]=min(f[i &1][j], f[i -1&1][j -1]+ nums[i][j]);if(j < i) f[i &1][j]=min(f[i &1][j], f[i -1&1][j]+ nums[i][j]);}longlong res = INT_MAX;for(int i =0; i < n; i++) res =min(res, f[n-1&1][i]);return res;}};
LeetCode 63. Unique Paths II
class Solution {
public://最后一步可以往下走,最后一步也可往右走intuniquePathsWithObstacles(vector<vector<int>>& g){int n = g.size(), m = g[0].size();
vector<vector<longlong>>f(n, vector<longlong>(m));for(int i =0; i < n; i++)for(int j =0; j < m; j++){if(g[i][j])continue;if(!i &&!j) f[i][j]=1;if(i >0) f[i][j]+= f[i -1][j];if(j >0) f[i][j]+= f[i][j -1];}return f[n-1][m-1];}};
LeetCode 91. Decode Ways
class Solution {
public:intnumDecodings(string s){int n = s.size();
vector<int>f(n +1);
f[0]=1;for(int i =1; i <= n; i++){if(s[i -1]!='0') f[i]+= f[i-1];if(i >=2){int t =(s[i -2]-'0')*10+ s[i -1]-'0';if(t >=10&& t <=26) f[i]+= f[i -2];}}return f[n];}};
LeetCode 198. House Robber
class Solution {
public:introb(vector<int>& nums){int n = nums.size();
vector<int>f(n+1),g(n+1);for(int i =1; i <= n; i++){
f[i]=max(f[i -1], g[i -1]);
g[i]= f[i -1]+ nums[i -1];}returnmax(f[n], g[n]);}};
LeetCode 300. Longest Increasing Subsequence
class Solution {
public:intlengthOfLIS(vector<int>& nums){int n = nums.size();
vector<int>f(n);for(int i =0; i < n; i++){
f[i]=1;for(int j =0; j < i; j++)if(nums[j]< nums[i])
f[i]=max(f[i], f[j]+1);}int res =0;for(int i =0; i < n; i++) res =max(res, f[i]);return res;}};
LeetCode 72. Edit Distance
class Solution {
public:intminDistance(string word1, string word2){int n = word1.size(), m = word2.size();
vector<vector<int>>f(n +1, vector<int>(m +1));for(int i =0; i <= n; i++) f[i][0]= i;for(int i =0; i <= m; i++) f[0][i]= i;for(int i =1; i <= n; i++)for(int j =1; j <= m; j++){
f[i][j]=min(f[i -1][j], f[i][j -1])+1;
f[i][j]=min(f[i][j], f[i -1][j -1]+(word1[i -1]!= word2[j -1]));}return f[n][m];}};
LeetCode 518. Coin Change 2
class Solution {
public:intchange(int m, vector<int>& coins){int n = coins.size();
vector<int>f(m +1);
f[0]=1;for(auto c : coins)for(int j = c; j <= m; j++)
f[j]+= f[j - c];return f[m];}};
LeetCode 664. Strange Printer
class Solution {
public:intstrangePrinter(string s){if(s.empty())return0;int n = s.size();
vector<vector<int>>f(n +1, vector<int>(n+1));for(int len =1; len <= n; len++)for(int l =0; l + len -1< n; l++){int r = l + len -1;
f[l][r]= f[l +1][r]+1;for(int k = l +1; k <= r; k++){if(s[k]== s[l])
f[l][r]=min(f[l][r], f[l][k -1]+ f[k +1][r]);}}return f[0][n -1];}};
LeetCode 10. Regular Expression Matching
class Solution {
public:
bool isMatch(string s, string p){int n = s.size(), m = p.size();
s =' '+ s, p =' '+ p;
vector<vector<bool>>f(n +1, vector<bool>(m +1));for(int i =0; i <= n; i++)for(int j =0; j <= m; j++)if(!i &&!j) f[i][j]= true;else{if(j +1<= m && p[j +1]=='*')continue;if(p[j]!='*'){if(p[j]=='.'|| s[i]== p[j])if(i >0&& j >0)
f[i][j]= f[i -1][j -1];}else{if(j >=2) f[i][j]= f[i][j -2];if(i >0& j >0){if(p[j -1]=='.'|| s[i]== p[j -1])if(f[i -1][j])
f[i][j]= true;}}}return f[n][m];}};