LeetCode 图解算法数据结构
替换空格
class Solution {
public:
string replaceSpace(string s) {
string res;
for(auto c:s){
if(c!=' '){
res+=c;
continue;
}
res+="%20";
}
return res;
}
};
从尾到头打印链表
方法一:递归
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
vector<int> reversePrint(ListNode* head) {
vector<int> res;
if(head==NULL){
return res;
}
res=reversePrint(head->next);
res.push_back(head->val);
return res;
}
};
方法二:栈
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
vector<int> reversePrint(ListNode* head) {
vector<int> res;
stack<int> stack;
while(head!=NULL){
stack.push(head->val);
head=head->next;
}
while(!stack.empty()){
res.push_back(stack.top());
stack.pop();
}
return res;
}
};
用两个栈实现队列
class CQueue {
private:
stack<int> stack1;
stack<int> stack2;
public:
CQueue() {
}
void appendTail(int value) {
stack1.push(value);
}
int deleteHead() {
int res=-1;
if(stack1.empty() && stack2.empty()){
return res;
}
if(!stack2.empty()){
res=stack2.top();
stack2.pop();
return res;
}
while(!stack1.empty()){
stack2.push(stack1.top());
stack1.pop();
}
res=stack2.top();
stack2.pop();
return res;
}
};
/**
* Your CQueue object will be instantiated and called as such:
* CQueue* obj = new CQueue();
* obj->appendTail(value);
* int param_2 = obj->deleteHead();
*/
表示数值的字符串
class Solution {
private:
bool scanUnsignedInteger(string &s,int &index){
int pos=index;
while(s[index]>='0' && s[index]<='9'){
index++;
}
return index>pos;
}
bool scanInteger(string &s,int &index){
if(s[index]=='+' || s[index]=='-'){
index++;
}
return scanUnsignedInteger(s,index);
}
public:
bool isNumber(string s) {
int index=0;
bool numeric=false;
while(s[index]==' '){
index++;
}
numeric=scanInteger(s,index);
if(s[index]=='.'){
index++;
numeric=(scanUnsignedInteger(s,index)||numeric);
}
if(s[index]=='e' || s[index]=='E'){
index++;
numeric=numeric&&scanInteger(s,index);
}
while(s[index]==' '){
index++;
}
return numeric&&(index==s.size());
}
};
反转链表
方法一:递归
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head==NULL || head->next==NULL){
return head;
}
ListNode *tail=reverseList(head->next);
head->next->next=head;
head->next=NULL;
return tail;
}
};
方法二:双指针
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head==NULL || head->next==NULL){
return head;
}
ListNode *cur=head;
ListNode *pre=NULL;
while(cur!=NULL){
ListNode *temp=cur->next;
cur->next=pre;
pre=cur;
cur=temp;
}
return pre;
}
};
包含min函数的栈
class MinStack {
private:
stack<int> stack;
vector<int> minNums;
public:
/** initialize your data structure here. */
MinStack() {
}
void push(int x) {
stack.push(x);
if(minNums.empty()){
minNums.push_back(x);
}
else {
minNums.push_back(std::min(minNums[minNums.size()-1],x));
}
}
void pop() {
stack.pop();
minNums.pop_back();
}
int top() {
return stack.top();
}
int min() {
return minNums[minNums.size()-1];
}
};
/**
* 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->min();
*/
复杂链表的复制
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
*/
class Solution {
public:
Node* copyRandomList(Node* head) {
if(head==NULL){
return head;
}
Node *cur=head;
while(cur!=NULL){
Node *temp=new Node(cur->val);
temp->next=cur->next;
cur->next=temp;
cur=temp->next;
}
cur=head;
while(cur!=NULL){
Node *temp=cur->next;
temp->random=cur->random==NULL?NULL:cur->random->next;
cur=temp->next;
}
cur=head;
Node *newHead=head->next;
while(cur!=NULL){
Node *temp=cur->next;
cur->next=temp->next;
temp->next=cur->next==NULL?NULL:cur->next->next;
cur=cur->next;
}
return newHead;
}
};
拼接 + 拆分
左旋转字符串
class Solution {
public:
string reverseLeftWords(string s, int n) {
string res;
for(int i=n;i<s.length();i++){
res+=s[i];
}
for(int i=0;i<n;i++){
res+=s[i];
}
return res;
}
};
滑动窗口的最大值
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
vector<int> deque,res;
if(nums.empty()){
return res;
}
int max=0;
for(int i=0;i<k;i++){
if(nums[i]>max){
max=nums[i];
}
deque.push_back(nums[i]);
}
res.push_back(max);
for(int i=k;i<nums.size();i++){
max=nums[i];
deque.erase(deque.begin());
for(int j=0;j<deque.size();j++){
if(deque[j]>max){
max=deque[j];
}
}
deque.push_back(nums[i]);
res.push_back(max);
}
return res;
}
};
队列的最大值
class MaxQueue {
private:
queue<int> queue;
deque<int> deque;
public:
MaxQueue() {
}
int max_value() {
if(queue.empty()){
return -1;
}
return deque.front();
}
void push_back(int value) {
queue.push(value);
if(deque.empty()){
deque.push_back(value);
}
else {
while(!deque.empty() && deque.back()<value){
deque.pop_back();
}
deque.push_back(value);
}
}
int pop_front() {
if(queue.empty()){
return -1;
}
int res=queue.front();
if(res==deque.front()){
deque.pop_front();
}
queue.pop();
return res;
}
};
/**
* Your MaxQueue object will be instantiated and called as such:
* MaxQueue* obj = new MaxQueue();
* int param_1 = obj->max_value();
* obj->push_back(value);
* int param_3 = obj->pop_front();
*/
把字符串转换成整数
class Solution {
public:
int strToInt(string str) {
int index=0,res=0,symbol=1,bndry=INT_MAX/10;
while(str[index]==' '){
index++;
}
if(str[index]=='-'){
symbol=-1;
}
if(str[index]=='-' || str[index]=='+'){
index++;
}
for(int i=index;i<str.length();i++){
if(str[i]<'0' || str[i]>'9'){
break;
}
if(res>bndry || (res>=bndry && str[i]>'7')){
return symbol==1?INT_MAX:INT_MIN;
}
res=res*10+(str[i]-'0');
}
return symbol*res;
}
};
斐波那契数列
class Solution {
public:
int fib(int n) {
int a=0,b=1;
if(n==0){
return a;
}
for(int i=2;i<=n;i++){
int temp=a;
a=b;
b=(temp+b)%1000000007;
}
return b;
}
};
青蛙跳台阶问题
class Solution {
public:
int numWays(int n) {
int a=1,b=1;
if(n==0 || n==1){
return 1;
}
for(int i=2;i<=n;i++){
int temp=a;
a=b;
b=(temp+b)%1000000007;
}
return b;
}
};
连续子数组的最大和
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int max=nums[0],temp=nums[0];
for(int i=1;i<nums.size();i++){
temp=std::max(temp+nums[i],nums[i]);
max=std::max(max,temp);
}
return max;
}
};
把数字翻译成字符串
class Solution {
public:
int translateNum(int num) {
int a=1,b=1;
while(num>9){
int end=num%100;
int c=end>=10 && end<=25?a+b:a;
b=a;
a=c;
num/=10;
}
return a;
}
};
礼物的最大价值
class Solution {
public:
int maxValue(vector<vector<int>>& grid) {
int rows=grid.size(),cols=grid[0].size();
//初始化第一行
for(int i=1;i<cols;i++){
grid[0][i]+=grid[0][i-1];
}
//初始化第一列
for(int i=1;i<rows;i++){
grid[i][0]+=grid[i-1][0];
}
for(int i=1;i<rows;i++){
for(int j=1;j<cols;j++){
grid[i][j]+=max(grid[i-1][j],grid[i][j-1]);
}
}
return grid[rows-1][cols-1];
}
};
最长不含重复字符的子字符串
class Solution {
public:
int lengthOfLongestSubstring(string s) {
unordered_map<char,int> map;
int maxLength=0,preMax=0;
for(int i=0;i<s.length();i++){
if(map.count(s[i])==0){
preMax++;
map.insert(make_pair(s[i],i));
}
else {
if(preMax<i-map[s[i]]){
preMax++;
}
else {
preMax=i-map[s[i]];
}
map[s[i]]=i;
}
maxLength=max(preMax,maxLength);
}
return max(preMax,maxLength);
}
};
解题思路
本题主要需要弄懂状态转移方程即可
丑数
class Solution {
public:
int nthUglyNumber(int n) {
vector<int> nums(1,1);
int a=0,b=0,c=0;
while(nums.size()<n){
int temp=min(min(nums[a]*2,nums[b]*3),nums[c]*5);
nums.push_back(temp);
if(temp==nums[a]*2){
a++;
}
if(temp==nums[b]*3){
b++;
}
if(temp==nums[c]*5) {
c++;
}
}
return nums[nums.size()-1];
}
};
n个骰子的点数
class Solution {
public:
vector<double> dicesProbability(int n) {
vector<double> probability(6,1.0/6);
for(int i=1;i<n;i++){
vector<double> temp((i+1)*5+1,0);
for(int j=0;j<probability.size();j++){
for(int k=j;k<j+6;k++){
temp[k]+=(probability[j]/6.0);
}
}
probability=temp;
}
return probability;
}
};
股票的最大利润
class Solution {
public:
int maxProfit(vector<int>& prices) {
if(prices.empty()){
return 0;
}
int profit=0,minPrice=prices[0];
for(auto price:prices){
if(price<minPrice){
minPrice=price;
}
profit=max(price-minPrice,profit);
}
return profit;
}
};
矩阵中的路径
class Solution {
public:
bool dfs(vector<vector<char>>& board, string word, int i, int j, int k){
if(i>=board.size() || i<0 || j>=board[0].size() || j<0 || board[i][j]!=word[k])
return false;
if(k==word.size()-1)
return true;
board[i][j]=' ';
bool res = dfs(board, word, i-1, j, k+1) || dfs(board, word, i+1, j, k+1) || dfs(board, word, i, j-1, k+1) || dfs(board, word, i, j+1, k+1);
board[i][j]=word[k];
return res;
}
bool exist(vector<vector<char>>& board, string word) {
int rows=board.size();
int cols=board[0].size();
for(int i=0;i<rows;i++){
for(int j=0;j<cols;j++){
if(dfs(board, word, i, j, 0))
return true;
}
}
return false;
}
};
DFS 解析:
递归参数: 当前元素在矩阵 board 中的行列索引 i 和 j ,当前目标字符在 word 中的索引 k 。
终止条件:
返回 false
:
-
行或列索引越界
-
当前矩阵元素与目标字符不同
-
当前矩阵元素已访问过 ( (3) 可合并至 (2) ) 。
返回 true
: k = len(word) - 1
,即字符串 word 已全部匹配。
递推工作:
标记当前矩阵元素: 将 board[i][j]
修改为 空字符 ''
,代表此元素已访问过,防止之后搜索时重复访问。
搜索下一单元格: 朝当前元素的 上、下、左、右 四个方向开启下层递归,使用 或
连接 (代表只需找到一条可行路径就直接返回,不再做后续 DFS ),并记录结果至 res 。
还原当前矩阵元素: 将 board[i][j]
元素还原至初始值,即 word[k]
。
返回值: 返回布尔量 res ,代表是否搜索到目标字符串。
机器人的运动范围
class Solution {
public:
int dfs(vector<vector<bool>>& isVisited,int i, int j, int m,int n,int k){
if(i<0 || i>=m || j<0 || j>=n || isVisited[i][j])
return 0;
int temp=0,row=i,col=j;
while(row!=0){
temp+=(row%10);
row/=10;
}
while(col!=0){
temp+=(col%10);
col/=10;
}
if(temp>k){
isVisited[i][j]=1;
return 0;
}
isVisited[i][j]=1;
int res=1;
res+=(dfs(isVisited, i-1, j, m, n, k) + dfs(isVisited, i+1, j, m, n, k) + dfs(isVisited, i, j-1, m, n, k) + dfs(isVisited, i, j+1, m, n, k));
return res;
}
int movingCount(int m, int n, int k) {
vector<vector<bool>> isVisited(m,vector<bool>(n,0));
return dfs(isVisited,0,0,m,n,k);
}
};
树的子结构
/**
* 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:
bool isEqual(TreeNode* A, TreeNode* B){
if(B==NULL)
return true;
if(A==NULL || A->val!=B->val)
return false;
return isEqual(A->left,B->left) && isEqual(A->right,B->right);
}
bool isSubStructure(TreeNode* A, TreeNode* B) {
return (A!=NULL && B!=NULL) && (isEqual(A,B) || isSubStructure(A->left,B) || isSubStructure(A->right,B));
}
};
二叉树的镜像
/**
* 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:
TreeNode* mirrorTree(TreeNode* root) {
if(root==NULL){
return NULL;
}
TreeNode *temp=root->left;
root->left=mirrorTree(root->right);
root->right=mirrorTree(temp);
return root;
}
};
对称的二叉树
/**
* 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:
bool symmetric(TreeNode *left,TreeNode *right){
if(left==NULL && right==NULL){
return true;
}
if(left==NULL || right==NULL){
return false;
}
if(left->val!=right->val){
return false;
}
return symmetric(left->left,right->right) && symmetric(left->right,right->left);
}
bool isSymmetric(TreeNode* root) {
if(root==NULL)
return true;
return symmetric(root->left,root->right);
}
};
从上到下打印二叉树
/**
* 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:
vector<int> levelOrder(TreeNode* root) {
vector<int> res;
if(root==NULL){
return res;
}
queue<TreeNode*> queue;
queue.push(root);
while(!queue.empty()){
for(int i=0;i<queue.size();i++){
TreeNode *node=queue.front();
res.push_back(node->val);
if(node->left!=NULL){
queue.push(node->left);
}
if(node->right!=NULL){
queue.push(node->right);
}
queue.pop();
}
}
return res;
}
};
从上到下打印二叉树 ΙΙ
/**
* 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:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
if(root==NULL){
return res;
}
queue<TreeNode*> queue;
queue.push(root);
while(!queue.empty()){
vector<int> row;
int times=queue.size();
for(int i=0;i<times;i++){
TreeNode *node=queue.front();
row.push_back(node->val);
if(node->left!=NULL){
queue.push(node->left);
}
if(node->right!=NULL){
queue.push(node->right);
}
queue.pop();
}
res.push_back(row);
}
return res;
}
};
从上到下打印二叉树 ΙΙΙ
/**
* 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:
vector<vector<int>> levelOrder(TreeNode* root) {
deque<TreeNode*> deque;
vector<vector<int>> res;
if(root != NULL) deque.push_back(root);
while(!deque.empty()) {
// 打印奇数层
vector<int> tmp;
for(int i = deque.size(); i > 0; i--) {
// 从左向右打印
TreeNode* node = deque.front();
deque.pop_front();
tmp.push_back(node->val);
// 先左后右加入下层节点
if(node->left != NULL) deque.push_back(node->left);
if(node->right != NULL) deque.push_back(node->right);
}
res.push_back(tmp);
if(deque.empty()) break; // 若为空则提前跳出
// 打印偶数层
tmp.clear();
for(int i = deque.size(); i > 0; i--) {
// 从右向左打印
TreeNode* node = deque.back();
deque.pop_back();
tmp.push_back(node->val);
// 先右后左加入下层节点
if(node->right != NULL) deque.push_front(node->right);
if(node->left != NULL) deque.push_front(node->left);
}
res.push_back(tmp);
}
return res;
}
};
二叉树中和为某一值的路径
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
void dfs(vector<vector<int>>& res,vector<int>& row,TreeNode *node,int sum,int target){
sum+=node->val;
row.push_back(node->val);
if(sum==target && node->left== nullptr && node->right== nullptr){
res.push_back(row);
}
if(node->left!= nullptr){
dfs(res,row,node->left,sum,target);
row.pop_back();
}
if(node->right!= nullptr){
dfs(res,row,node->right,sum,target);
row.pop_back();
}
}
vector<vector<int>> pathSum(TreeNode* root, int target) {
vector<vector<int>> res;
if(root==NULL){
return res;
}
vector<int> row;
dfs(res,row,root,0,target);
return res;
}
};
二叉搜索树与双向链表
/*
// Definition for a Node.
class Node {
public:
int val;
Node* left;
Node* right;
Node() {}
Node(int _val) {
val = _val;
left = NULL;
right = NULL;
}
Node(int _val, Node* _left, Node* _right) {
val = _val;
left = _left;
right = _right;
}
};
*/
class Solution {
public:
void dfs(vector<Node*>& nodes,Node *root){
if(root==NULL){
return;
}
dfs(nodes,root->left);
nodes.push_back(root);
dfs(nodes,root->right);
}
Node* treeToDoublyList(Node* root) {
if(root==NULL){
return NULL;
}
vector<Node*> nodes;
dfs(nodes,root);
Node *pre=nodes[0];
for(int i=1;i<nodes.size();i++){
pre->right=nodes[i];
nodes[i]->left=pre;
pre=nodes[i];
}
Node *start=nodes[0];
Node *end=nodes[nodes.size()-1];
start->left=end;
end->right=start;
Node *head=new Node(0);
head->right=start;
return start;
}
};
字符串的排列
class Solution {
public:
void dfs(vector<string>& res,string s,int index){
if(index==s.length()-1){
res.push_back(s);
return;
}
unordered_set<char> cs;
for(int i=index;i<s.length();i++){
if(cs.find(s[i])!=cs.end())
continue;
cs.insert(s[i]);
swap(s[i],s[index]);
dfs(res,s,index+1);
swap(s[i],s[index]);
}
}
vector<string> permutation(string s) {
vector<string> res;
dfs(res,s,0);
return res;
}
};
二叉搜索树的第k大节点
方法一
/**
* 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:
void dfs(vector<int>& nums,TreeNode *node){
if(node==NULL){
return;
}
dfs(nums,node->left);
nums.push_back(node->val);
dfs(nums,node->right);
}
int kthLargest(TreeNode* root, int k) {
vector<int> nums;
dfs(nums,root);
return nums[nums.size()-k];
}
};
方法二
/**
* 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:
void dfs(int& res,TreeNode *node,int& k,bool isOk){
if(node==NULL || isOk){
return;
}
dfs(res,node->right,k,isOk);
k--;
if(k==0){
res=node->val;
isOk=true;
}
dfs(res,node->left,k,isOk);
}
int kthLargest(TreeNode* root, int k) {
int res;
dfs(res,root,k, false);
return res;
}
};
二叉树的深度
/**
* 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:
void dfs(int& maxDepth,TreeNode *node,int depth){
if(node==NULL)
return;
depth++;
maxDepth=max(maxDepth,depth);
dfs(maxDepth,node->left,depth);
dfs(maxDepth,node->right,depth);
}
int maxDepth(TreeNode* root) {
int maxDepth=0;
dfs(maxDepth,root,0);
return maxDepth;
}
};
平衡二叉树
/**
* 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 recur(TreeNode *node){
if(node==NULL){
return 0;
}
int left=recur(node->left);
if(left==-1){
return -1;
}
int right=recur(node->right);
if(right==-1){
return -1;
}
return abs(left-right)<2?max(left,right)+1:-1;
}
bool isBalanced(TreeNode* root) {
int res=recur(root);
return res!=-1;
}
};
求 1 + 2 + ... + n
class Solution {
public:
int sumNums(int n) {
if(n==1)
return 1;
return n+sumNums(n-1);
}
};
二叉搜索树的最近公共祖先
/**
* 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:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(p->val>q->val){
swap(p,q);
}
while(root!=NULL){
if(root->val<p->val){
root=root->right;
}
else if(root->val>q->val){
root=root->left;
}
else {
break;
}
}
return root;
}
};
二叉树的最近公共祖先
/**
* 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:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root==NULL || root==p || root==q)
return root;
TreeNode *left=lowestCommonAncestor(root->left,p,q);
TreeNode *right=lowestCommonAncestor(root->right,p,q);
if(left==NULL && right==NULL)
return NULL;
if(left==NULL)
return right;
if(right==NULL)
return left;
return root;
}
};
重建二叉树
/**
* 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:
TreeNode* recur(vector<int>& preorder,unordered_map<int,int>& map,int root,int left,int right){
if(left>right)
return NULL;
TreeNode *node=new TreeNode(preorder[root]);
int i=map[preorder[root]];
node->left=recur(preorder,map,root+1,left,i-1);
node->right=recur(preorder,map,root+i-left+1,i+1,right);
return node;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
unordered_map<int,int> map;
for(int i=0;i<inorder.size();i++){
map.insert(make_pair(inorder[i],i));
}
return recur(preorder,map,0,0,inorder.size()-1);
}
};
数值的整数次方
class Solution {
public:
double myPow(double x, int n) {
if(x==0.0f){
return x;
}
double res=1.0;
long b=n;
if(b<0){
x=1.0/x;
b=-b;
}
while(b>0){
if(b&1==1)
res*=x;
x*=x;
b>>=1;
}
return res;
}
};
打印从 1 到最大的 n 位数
class Solution {
public:
vector<int> printNumbers(int n) {
int times=1;
while(n>0){
times*=10;
n--;
}
vector<int> res;
for(int i=1;i<times;i++){
res.push_back(i);
}
return res;
}
};
二叉搜索树的后序遍历序列
class Solution {
public:
bool verifyPostorder(vector<int>& postorder) {
stack<int> stack;
int root=INT_MAX;
for(int i=postorder.size()-1;i>=0;i--){
if(postorder[i]>root)
return false;
while(!stack.empty() && stack.top()>postorder[i]){
root=stack.top();
stack.pop();
}
stack.push(postorder[i]);
}
return true;
}
};
数组中的逆序对
class Solution {
public:
int mergeSort(int left,int right,vector<int> &nums,vector<int>& temp){
if(left>=right)
return 0;
int mid=(left+right)/2;
int res=mergeSort(left,mid,nums,temp)+mergeSort(mid+1,right,nums,temp);
int i=left,j=mid+1;
for(int k=left;k<=right;k++){
temp[k]=nums[k];
}
for(int k=left;k<=right;k++){
if(i==mid+1){
nums[k]=temp[j++];
}
else if(j==right+1 || temp[i]<=temp[j]){
nums[k]=temp[i++];
}
else {
nums[k]=temp[j++];
res+=mid-i+1;
}
}
return res;
}
int reversePairs(vector<int>& nums) {
vector<int> temp(nums.size());
return mergeSort(0,nums.size()-1,nums,temp);
}
};
最小的 k 个数
class Solution {
public:
void mergeSort(vector<int>& nums,int left,int right){
if(left>=right)
return;
int mid=(left+right)/2;
mergeSort(nums,left,mid);
mergeSort(nums,mid+1,right);
int temp[right-left+1];
for(int k=left;k<=right;k++){
temp[k-left]=nums[k];
}
int i=0,j=mid-left+1;
for(int k=left;k<=right;k++){
if(i==mid-left+1){
nums[k]=temp[j++];
}
else if(j==right-left+1 || temp[i]<=temp[j]){
nums[k]=temp[i++];
}
else {
nums[k]=temp[j++];
}
}
}
vector<int> getLeastNumbers(vector<int>& arr, int k) {
int size=arr.size();
mergeSort(arr,0,arr.size()-1);
for(int i=size-k;i>0;i--){
arr.pop_back();
}
return arr;
}
};
数据流中的中位数
class MedianFinder {
private:
priority_queue<int,vector<int>,greater<int>> A;//小顶堆,用于存储较大的一半
priority_queue<int,vector<int>,less<int>> B;//大顶堆,用于存储较小的一半
public:
/** initialize your data structure here. */
MedianFinder() {
}
void addNum(int num) {
if(A.size()!=B.size()){
A.push(num);
B.push(A.top());
A.pop();
}
else {
B.push(num);
A.push(B.top());
B.pop();
}
}
double findMedian() {
return A.size()==B.size()?(A.top()+B.top())/2.0:A.top();
}
};
/**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder* obj = new MedianFinder();
* obj->addNum(num);
* double param_2 = obj->findMedian();
*/
把数组排成最小的数
class Solution {
public:
void quickSort(vector<string>& strs,int left,int right){
if(left>=right)
return;
int i=left,j=right;
while(i<j){
while(strs[j]+strs[left]>=strs[left]+strs[j] && i<j)
j--;
while(strs[i]+strs[left]<=strs[left]+strs[i] && i<j)
i++;
swap(strs[i],strs[j]);
}
swap(strs[left],strs[i]);
quickSort(strs,left,i-1);
quickSort(strs,i+1,right);
}
string minNumber(vector<int>& nums) {
vector<string> strs;
for(auto num:nums){
strs.push_back(to_string(num));
}
string res;
quickSort(strs,0,strs.size()-1);
for(auto str:strs){
res.append(str);
}
return res;
}
};
扑克牌中的顺子
class Solution {
public:
void mergeSort(vector<int>& nums,int left,int right){
if(left>=right)
return;
int mid=(left+right)/2;
mergeSort(nums,left,mid);
mergeSort(nums,mid+1,right);
int temp[right-left+1];
for(int k=left;k<=right;k++){
temp[k-left]=nums[k];
}
int i=0,j=mid-left+1;
for(int k=left;k<=right;k++){
if(i==mid-left+1)
nums[k]=temp[j++];
else if(j==right-left+1 || temp[i]<=temp[j])
nums[k]=temp[i++];
else
nums[k]=temp[j++];
}
}
bool isStraight(vector<int>& nums) {
mergeSort(nums,0,nums.size()-1);
int joker=0;
for(int i=0;i<nums.size()-1;i++){
if(nums[i]==0){
joker++;
continue;
}
else if(nums[i]==nums[i+1])
return false;
}
return nums[nums.size()-1]-nums[joker]<5;
}
};
数组中重复的数字
class Solution {
public:
int findRepeatNumber(vector<int>& nums) {
unordered_map<int,bool> map;
for(auto num:nums){
if(map[num])
return num;
map[num]=true;
}
return -1;
}
};
二维数组中的查找
class Solution {
public:
bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
for(int i=0;i<matrix.size();i++){
if(matrix[i].size()>0 && (matrix[i][0]>target || matrix[i][matrix[i].size()-1]<target))
continue;
for(int j=0;j<matrix[i].size();j++){
if(matrix[i][j]==target)
return true;
}
}
return false;
}
};
旋转数组的最小数字
class Solution {
public:
int minArray(vector<int>& numbers) {
int left=0,right=numbers.size()-1;
while(left<right){
int mid=(left+right)/2;
if(numbers[mid]>numbers[right])
left=mid+1;
else if(numbers[mid]<numbers[right])
right=mid;
else {
int temp=left;
for(int i=left+1;i<right;i++){
if(numbers[i]<numbers[temp])
temp=i;
}
return numbers[temp];
}
}
return numbers[left];
}
};
第一个只出现一次的字符
class Solution {
public:
char firstUniqChar(string s) {
queue<char> queue;
unordered_map<char,int> map;
for(auto c:s){
if(map.count(c)==0){
queue.push(c);
map[c]=1;
}
else {
map[c]=++map[c];
}
}
while(!queue.empty()){
char c = queue.front();
if(map[c]==1){
return c;
}
queue.pop();
}
return ' ';
}
};
在排序数组中查找数字 Ι
class Solution {
public:
int search(vector<int>& nums, int target) {
int left=0,right=nums.size()-1;
int res=0;
while(left<=right){
int mid=(left+right)/2;
if(nums[mid]<target)
left=mid+1;
else if(nums[mid]>target)
right=mid-1;
else{
res+=1;
int p1=mid-1,p2=mid+1;
while(p1>=0 && nums[p1]==target){
res++;
p1--;
}
while(p2<=nums.size()-1 && nums[p2]==target){
res++;
p2++;
}
return res;
}
}
return res;
}
};
0 ~ n-1 中缺失的数字
class Solution {
public:
int missingNumber(vector<int>& nums) {
int left=0,right=nums.size()-1;
while(left<right){
int mid=(left+right)/2;
if(nums[mid]==mid){
left=mid+1;
}
else {
right=mid;
}
}
return nums[nums.size()-1]==nums.size()-1?nums[left]+1:nums[left]-1;
}
};
删除链表的节点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* deleteNode(ListNode* head, int val) {
ListNode* pre=new ListNode(0);
pre->next=head;
ListNode* cur=head;
while(cur!=NULL){
if(cur->val==val){
pre->next=cur->next;
cur->next=NULL;
break;
}
else {
cur=cur->next;
pre=pre->next;
}
}
return cur==head?pre->next:head;
}
};
调整数组顺序使奇数位于偶数前面
class Solution {
public:
vector<int> exchange(vector<int>& nums) {
int left=0,right=nums.size()-1;
while(left<right){
while(left<right && nums[left]%2==1)
left++;
while(left<right && nums[right]%2==0)
right--;
swap(nums[left],nums[right]);
left++;
right--;
}
return nums;
}
};
链表中倒数第 k 个节点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* getKthFromEnd(ListNode* head, int k) {
ListNode* p1=head;
ListNode* p2=head;
for(int i=0;i<k;i++){
p2=p2->next;
}
while(p2!=NULL && p2->next!=NULL){
p1=p1->next;
p2=p2->next;
}
return p2==NULL?p1:p1->next;
}
};
合并两个排序的链表
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if(l1==NULL || l2==NULL){
return l1==NULL?l2:l1;
}
if(l1->val<=l2->val){
l1->next=mergeTwoLists(l1->next,l2);
}
else{
l2->next=mergeTwoLists(l1,l2->next);
}
return l1->val<=l2->val?l1:l2;
}
};
两个链表的第一个公共节点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* p1=headA;
ListNode* p2=headB;
while(p1!=p2){
p1=p1!=NULL?p1->next:headB;
p2=p2!=NULL?p2->next:headA;
}
return p1;
}
};/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* p1=headA;
ListNode* p2=headB;
while(p1!=p2){
p1=p1!=NULL?p1->next:headB;
p2=p2!=NULL?p2->next:headA;
}
return p1;
}
};
和为 s 的两个数字
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
int left=0,right=nums.size()-1;
vector<int> res;
while(left<right){
int sum=nums[left]+nums[right];
if(sum>target){
right--;
}
else if(sum<target){
left++;
}
else{
res.push_back(nums[left]);
res.push_back(nums[right]);
break;
}
}
return res;
}
};
翻转单词顺序
class Solution {
public:
string reverseWords(string s) {
if(s.length()==0){
return s;
}
int left=0,right=0;
bool hasLetter=false;
string res="";
while(right<s.length()){
if(s[right]==' ' && !hasLetter){
left++;
right++;
continue;
}
if(s[right]==' '){
hasLetter=false;
res=' '+s.substr(left,right-left)+res;
right++;
left=right;
}
else {
hasLetter=true;
right++;
}
}
s[s.length()-1]==' '?res.erase(0,1):res=s.substr(left,right-left)+res;
return res;
}
};
二进制中 1 的个数
class Solution {
public:
int hammingWeight(uint32_t n) {
int res=0;
while(n!=0){
n%2==0?res:res++;
n>>=1;
}
return res;
}
};
数组中数字出现的次数
class Solution {
public:
vector<int> singleNumbers(vector<int>& nums) {
int x = 0, y = 0, n = 0, m = 1;
for(int num : nums) // 1. 遍历异或
n ^= num;
while((n & m) == 0) // 2. 循环左移,计算 m
m <<= 1;
for(int num : nums) { // 3. 遍历 nums 分组
if(num & m) x ^= num; // 4. 当 num & m != 0
else y ^= num; // 4. 当 num & m == 0
}
return vector<int> {x, y}; // 5. 返回出现一次的数字
}
};
不用加减乘除做加法
class Solution {
public:
int add(int a, int b) {
while(b!=0){
int c=(unsigned int)(a & b) << 1;
a^=b;
b=c;
}
return a;
}
};
剪绳子
class Solution {
public:
int cuttingRope(int n) {
if(n<=3)
return n-1;
int a=n/3,b=n%3;
if(b==0)
return pow(3,a);
if(b==1)
return pow(3,a-1)*4;
return pow(3,a)*2;
}
};
剪绳子 ΙΙ
class Solution {
public:
int cuttingRope(int n) {
if(n<=3)
return n-1;
int b=n%3,mod=1000000007;
long rem=1,x=3;
for(int a=n/3-1;a>0;a/=2){
if(a&1==1){
rem=(rem*x)%mod;
}
x=(x*x)%mod;
}
if(b==0)
return rem*3%mod;
if(b==1)
return rem*4%mod;
return rem*6%mod;
}
};
数组中出现次数超过一半的数字
class Solution {
public:
// hash + 计数
/*int hashCount(vector<int>& nums) {
unordered_map<int,int> map;
for(auto num:nums){
if(map.count(num)==0){
map[num]=1;
}
else if(map[num]+1>nums.size()/2){
return num;
}
else{
map[num]+=1;
}
}
return map.begin()->first;
}*/
//快速排序取中间值
/*void quickSort(vector<int>& nums,int left,int right){
if(left>=right)
return;
int i=left,j=right;
while(i<j){
while(i<j && nums[j]>=nums[left])
j--;
while(i<j && nums[i]<=nums[left])
i++;
swap(nums[i],nums[j]);
}
swap(nums[i],nums[left]);
quickSort(nums,left,i-1);
quickSort(nums,i+1,right);
}*/
//归并排序取中间值
/*void mergeSort(vector<int>& nums,int left,int right){
if(left>=right){
return;
}
int mid=(left+right)/2;
mergeSort(nums,left,mid);
mergeSort(nums,mid+1,right);
int temp[right-left+1];
for(int k=left;k<=right;k++){
temp[k-left]=nums[k];
}
int i=0,j=mid-left+1;
for(int k=left;k<=right;k++){
if(i==mid-left+1){
nums[k]=temp[j++];
}
else if(j==right-left+1 || temp[i]<temp[j]){
nums[k]=temp[i++];
}
else{
nums[k]=temp[j++];
}
}
}*/
// 摩尔投票法
int mooreVote(vector<int>& nums){
int res=0,vate=0;
for(auto num:nums){
if(vate==0){
res=num;
vate++;
}
else if(num!=res){
vate--;
}
else{
vate++;
}
}
return res;
}
int majorityElement(vector<int>& nums) {
return mooreVote(nums);
}
};
1 ~ n 整数中 1 出现的次数
class Solution {
public:
int countDigitOne(int n) {
long digit=1;
int high=n/10,cur=n%10,low=0,res=0;
while(high!=0 || cur!=0){
if(cur==0){
res+=high*digit;
}
else if(cur==1){
res+=high*digit+low+1;
}
else {
res+=(high+1)*digit;
}
low+=cur*digit;
cur=high%10;
high/=10;
digit*=10;
}
return res;
}
};
题目解析:1 ~ n 整数中 1 出现的次数
数字序列中某一位的数字
class Solution {
public:
int findNthDigit(int n) {
int digit=1;
long start=1,count=9;
while(n>count){
n-=count;
digit++;
start*=10;
count=9*start*digit;
}
int num=start+(n-1)/digit;
string s=to_string(num);
return (int)s[(n-1)%digit]-'0';
}
};
和为 s 的连续正数序列
class Solution {
public:
vector<vector<int>> findContinuousSequence(int target) {
int i=1;
double j=2.0;
vector<vector<int>> res;
while(i<j){
j=(-1+sqrt(1+4*(2*target+(long)i*i-i)))/2;
if(j==(int)j){
vector<int> ans;
for(int k=i;k<=(int)j;k++){
ans.push_back(k);
}
res.push_back(ans);
}
i++;
}
return res;
}
};
题目解析:和为 s 的连续正数序列
圆圈中最后剩下的数字
class Solution {
public:
int lastRemaining(int n, int m) {
int x=0;
for(int i=2;i<=n;i++){
x=(m+x)%i;
}
return x;
}
};
题目解析:圆圈中最后剩下的数字
构建乘积数组
class Solution {
public:
vector<int> constructArr(vector<int>& a) {
int len=a.size();
if(len==0)
return {};
vector<int> res(len,1);
for(int i=1;i<len;i++){
res[i]=res[i-1]*a[i-1];
}
int temp=1;
for(int i=len-2;i>=0;i--){
temp*=a[i+1];
res[i]*=temp;
}
return res;
}
};
题目解析:构建乘积数组
顺时针打印矩阵
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
if(matrix.empty())
return {};
vector<int> res;
int up=0,right=matrix[0].size()-1,down=matrix.size()-1,left=0;
while(true){
for(int i=left;i<=right;i++) res.push_back(matrix[up][i]);
if(++up>down) break;
for(int i=up;i<=down;i++) res.push_back(matrix[i][right]);
if(--right<left) break;
for(int i=right;i>=left;i--) res.push_back(matrix[down][i]);
if(--down<up) break;
for(int i=down;i>=up;i--) res.push_back(matrix[i][left]);
if(++left>right) break;
}
return res;
}
};
题目解析:顺时针打印矩阵
栈的压入、弹出序列
class Solution {
public:
bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
stack<int> stack;
int p=0;
for(auto num:pushed){
stack.push(num);
while(!stack.empty() && stack.top()==popped[p]){
stack.pop();
p++;
}
}
return stack.empty();
}
};
题目解析:栈的压入、弹出序列
-------------------------------------------
个性签名:独学而无友,则孤陋而寡闻。做一个灵魂有趣的人!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!
万水千山总是情,打赏一分行不行,所以如果你心情还比较高兴,也是可以扫码打赏博主,哈哈哈(っ•̀ω•́)っ✎⁾⁾!