剑指offer刷题
文章目录
- 剑指offer刷题
- 03 [数组中重复的数字]
- 04 [二维数组中的查找]
- 05 [替换空格]
- 06 [从尾到头打印链表]
- 07 [重建二叉树]
- 09 [用两个栈实现队列]
- 10-I [斐波那契数列]
- 10-II [青蛙跳台阶问题]
- 11 [旋转数组的最小数字]
- 12 [矩阵中的路径]
- 13 [机器人的运动范围]
- 14-I [剪绳子]
- 14-II [剪绳子 II]
- 15 [二进制中 1 的个数]
- 16 [数值的整数次方]
- 17 [打印从 1 到最大的 n 位数] 数学
- 18 [删除链表的节点] 链表
- 19 [正则表达式匹配]
- 20 [表示数值的字符串]
- 21 [调整数组顺序使奇数位于偶数前面]
- 22 [链表中倒数第 k 个节点]
- 24 [反转链表]
- 25 [合并两个排序的链表]
- 26 [树的子结构]
- 27 [二叉树的镜像]
- 28 [对称的二叉树]
- 29 [顺时针打印矩阵]
- 30 [包含 min 函数的栈]
- 31 [栈的压入、弹出序列]
- 32-I [从上到下打印二叉树]
- 32-II [从上到下打印二叉树 II]
- 32-III [从上到下打印二叉树 III]
- 33 [二叉搜索树的后序遍历序列]
- 34 [二叉树中和为某一值的路径]
- 35 [复杂链表的复制]
- 36 [二叉搜索树与双向链表]
- 37 [序列化二叉树]
- 38 [字符串的排列]
- 39 [数组中出现次数超过一半的数字]
- 40 [最小的 k 个数]
- 41 [数据流中的中位数]
- 42 [连续子数组的最大和]
- 43 [1 ~ n 整数中 1 出现的次数]
- 44 [数字序列中某一位的数字]
- 45 [把数组排成最小的数] 排序
- 46 [把数字翻译成字符串]
- 47 [礼物的最大价值] 动态规划
- 48 [最长不含重复字符的子字符串]
- 49 [丑数]
- 50 [第一个只出现一次的字符]
- 51 [数组中的逆序对]
- 52 [两个链表的第一个公共节点] 链表
- 53-I [在排序数组中查找数字 I]
- 53-II [0 ~ n-1 中缺失的数字]
- 54 [二叉搜索树的第 k 大节点]
- 55-I [二叉树的深度]
- 55-II [平衡二叉树]
- 56-I [数组中数字出现的次数]
- 56-II [数组中数字出现的次数 II]
- 57 [和为 s 的两个数字]
- 57-II [和为 s 的连续正数序列]
- 58-I [翻转单词顺序]
- 58-II [左旋转字符串]
- 59-I [滑动窗口的最大值]
- 59-II [队列的最大值]
- 60 [n 个骰子的点数]
- 61 [扑克牌中的顺子]
- 62 [圆圈中最后剩下的数字]
- 63 [股票的最大利润]
- 64 [求 1+2+…+n]
- 65 [不用加减乘除做加法]
- 66 [构建乘积数组]
- 67 [把字符串转换成整数]
- 68-I [二叉搜索树的最近公共祖先]
- 68-II [二叉树的最近公共祖先]
- 补充题
03 [数组中重复的数字]
class Solution {
public:
int findRepeatNumber(vector<int>& nums) {
sort(nums.begin(),nums.end());
for(int i=0;i<nums.size();i++)
{
if(nums[i+1]==nums[i])
{
//cout<<nums[i]<<endl;
//break;
return nums[i];
}
}
return 0;
}
};
04 [二维数组中的查找]
class Solution {
public:
bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
if(matrix.empty()) return false;
if(matrix[0].empty()) return false;
int m = matrix.size();
int n = matrix[0].size();
for(int i=0;i<m;i++)
{
if(matrix[i][0]<=target&&matrix[i][n-1]>=target)
{
for(int j=0;j<n;j++)
{
if(matrix[i][j]==target)
return true;
}
}
}
return false;
}
};
05 [替换空格]
class Solution {
public:
string replaceSpace(string s) {
vector<int> place;
for(int i=0;i<s.size();i++)
{
if(s[i] == ' ')
{
place.push_back(i);
}
}
for(auto it=place.rbegin();it!=place.rend();it++)
{
int i = *it;
s[i] = '%';
s.insert(i+1,"20");
}
return s;
}
};
06 [从尾到头打印链表]
/**
* 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) {
int count = 0;
auto tmp = head;
while(tmp!=NULL)
{
count++;
tmp = tmp->next;
}
vector<int> result(count,0);
tmp = head;
while(tmp!=NULL)
{
result[--count] = tmp->val;
tmp = tmp->next;
}
return result;
}
};
07 [重建二叉树]
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
TreeNode* recursion(vector<int>& preorder,int p1,int p2,vector<int>& inorder,int q1,int q2)
{
if(p1>p2||q1>q2) return NULL;
TreeNode* newNode = new TreeNode(preorder[p1]);
int leftTreeLen;
for(int i=q1;i<=q2;i++)
{
if(preorder[p1] == inorder[i])
{
leftTreeLen = i-q1;
break;
}
}
//递归左子树
TreeNode* leftNode = recursion(preorder, p1+1, p1+leftTreeLen,inorder, q1, q1+leftTreeLen-1);
newNode->left = leftNode;
//递归右子树
TreeNode* rightNode = recursion(preorder, p1+leftTreeLen+1, p2,inorder, q1+leftTreeLen+1, q2);
newNode->right = rightNode;
return newNode;
}
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
TreeNode* root;
root = recursion(preorder,0,preorder.size()-1,inorder,0,inorder.size()-1);
return root;
}
};
09 [用两个栈实现队列]
class CQueue {
public:
stack<int> s1,s2;
CQueue() {
}
void appendTail(int value) {
s1.push(value);
}
int deleteHead() {
if(s2.empty())
{
if(s1.empty()) return -1;
while(!s1.empty())
{
s2.push(s1.top());
s1.pop();
}
}
int tmp = s2.top();
s2.pop();
return tmp;
}
};
/**
* Your CQueue object will be instantiated and called as such:
* CQueue* obj = new CQueue();
* obj->appendTail(value);
* int param_2 = obj->deleteHead();
*/
10-I [斐波那契数列]
class Solution {
public:
int fib(int n) {
int f0 = 0;
int f1 = 1;
int tmp;
if(n==0) return f0;
for(int i=0;i<n-1;i++)
{
//cout<<f1<<endl;
tmp = (f0+f1)%1000000007;
f0 = f1;
f1 = tmp;
}
//cout<<f1<<endl;
return f1;
}
};
10-II [青蛙跳台阶问题]
class Solution {
public:
int numWays(int n) {
if(n<=1) return 1;
int a1 = 1;
int a2 = 2;
int a;
for(int i=0;i<n-2;i++)
{
a = (a1+a2)%1000000007;
a1=a2;
a2 = a;
}
return a2;
}
};
11 [旋转数组的最小数字]
class Solution {
public:
int minArray(vector<int>& numbers) {
int size = numbers.size();
for(int i=0;i<size-1;i++)
{
if(numbers[i+1]<numbers[i])
{
return numbers[i+1];
}
}
return numbers[0];
}
};
12 [矩阵中的路径]
class Solution {
int iMax,jMax;
int size;
vector<vector<bool>> b;
vector<vector<char>> board1;
string word1;
public:
bool recursion(int i,int j,int pos)
{
//cout<<"i=="<<i<<"j="<<j<<"pos="<<pos<<"size="<<size<<endl;
if(pos==size-1) return true;
if(i+1<iMax&&b[i+1][j]&&board1[i+1][j]==word1[pos+1])
{
b[i+1][j] = false;
if(recursion(i+1,j,pos+1)) return true;
b[i+1][j] = true;
}
if(j+1<jMax&&b[i][j+1]&&board1[i][j+1]==word1[pos+1])
{
//cout<<"position="<<pos<<endl;
b[i][j+1] = false;
if(recursion(i,j+1,pos+1)) return true;
b[i][j+1] = true;
}
if(i-1>-1&&b[i-1][j]&&board1[i-1][j]==word1[pos+1])
{
b[i-1][j] = false;
if(recursion(i-1,j,pos+1)) return true;
b[i-1][j] = true;
}
if(j-1>-1&&b[i][j-1]&&board1[i][j-1]==word1[pos+1])
{
//cout<<"hahaha"<<endl;
//cout<<"ij_1b"<<i<<j-1<<" "<<b[i][j-1]<<endl;
b[i][j-1] = false;
if(recursion(i,j-1,pos+1)) return true;
b[i][j-1] = true;
}
return false;
}
bool exist(vector<vector<char>>& board, string word) {
//cout<<"to here"<<endl;
iMax = board.size();
jMax = board[0].size();
//cout<<"iMax="<<iMax<<"jMax"<<jMax<<endl;
vector<bool> tmp(jMax,true);
//cout<<"to here"<<endl;
b.resize(iMax,tmp);
board1 = board;
word1 = word;
size = word.size();
for(int i=0;i<iMax;i++)
{
for(int j=0;j<jMax;j++)
{
if(board[i][j]!=word[0]) continue;
b[i][j] = false;
//cout<<"ij="<<i<<" "<<j<<endl;
if(recursion(i,j,0)) return true;
b[i][j] = true;
}
}
return false;
}
};
13 [机器人的运动范围]
class Solution {
int result;
int digitSum(int i,int j)
{
int sum = 0;
while(1)
{
sum = sum+i%10;
if(i/10==0) break;
i = i/10;
}
while(1)
{
sum = sum+j%10;
if(j/10==0) break;
j = j/10;
}
return sum;
}
int recursion(int i,int j,int m,int n,vector<vector<bool>> &vis)
{
if(i+1<m&&j<n&&vis[i+1][j])
{
result++;
vis[i+1][j] = false;
recursion(i+1,j,m,n,vis);
}
if(i<m&&j+1<n&&vis[i][j+1])
{
vis[i][j+1] = false;
result++;
recursion(i,j+1,m,n,vis);
}
return 0;
}
public:
int movingCount(int m, int n, int k) {
vector<vector<bool>> vis(m,vector<bool>(n,true));
result = 1;
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
if(digitSum(i,j)>k)
{
vis[i][j] = false;
}
}
}
recursion(0,0,m,n,vis);
return result;
}
};
14-I [剪绳子]
class Solution {
public:
int cuttingRope(int n) {
vector<int> dp(n+1);
dp[2] = 1;
for(int i=3;i<n+1;i++)
{
for(int j=1;j<=i-j;j++)
{
//cout<<i<<endl;
//cout<<j<<endl;
dp[i] = max(dp[i],j*dp[i-j]);
dp[i] = max(dp[i],j*(i-j));
}
}
return dp[n];
}
};
14-II [剪绳子 II]
class Solution {
int mypow(int a,int n,int base)
{
long int tmp = base;
for(int i=0;i<n;i++)
{
tmp = tmp*a;
tmp = tmp%1000000007;
}
return tmp;
}
public:
int cuttingRope(int n) {
if(n==2) return 1;
if(n==3) return 2;
int num = ceil(n/3.0);
int rem = n%3;
int r;
if(rem==0)
{
r = (mypow(3,num,1));
}
else if(rem==1)
{
r = mypow(3,num-2,4);
}
else{
r = mypow(3,num-1,2);
}
return r;
}
};
15 [二进制中 1 的个数]
class Solution {
public:
int hammingWeight(uint32_t n) {
int count = 0;
int rem;
while(1)
{
rem = n%2;
if(rem==1)
{
count++;
}
n = n/2;
if(n==0) break;
}
return count;
}
};
16 [数值的整数次方]
class Solution {
public:
double myPow(double x, int n) {
if(x==1) return x;
double r = 1;
int k=n>0?n:-n;
for(int i=0;i<k;i++)
{
r = r*x;
}
cout<<r<<endl;
if(n<0)
{
r = 1.0/r;
}
cout<<r<<endl;
return r;
}
};
class Solution {
public:
double myPow(double x, int n)
{
if(x==1) return 1;
if(x == 0) return 0;
double res = 1;
long int k = (long int)(n);
if(n < 0)
{
x = 1/x;
k = -k;
}
//cout<<k<<" "<<x<<endl;
while(k!=0)
{
if(k%2)
{
res*=x;
}
x*=x;
k>>=1;
}
return res;
}
};
17 [打印从 1 到最大的 n 位数] 数学
class Solution {
public:
vector<int> printNumbers(int n) {
int M = pow(10,n)-1;
vector<int> res(M);
for(int i=1;i<=M;i++)
{
res[i-1] = i;
}
return res;
}
};
18 [删除链表的节点] 链表
/**
* 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) {
if(head->val==val) return head->next;
ListNode* cur = head;
ListNode* curLast = NULL;
while(1)
{
if(cur->val==val)
{
//cout<<cur->val<<endl;
curLast->next = cur->next;
break;
}
else
{
curLast = cur;
cur = cur->next;
}
}
return head;
}
};
19 [正则表达式匹配]
class Solution {
public:
bool isMatch(string s, string p) {
int m = s.size();
int n = p.size();
vector<vector<int>> f(m+1,vector<int>(n+1));
f[0][0] = true;
for(int i=0;i<n;i++)
{
if(p[i]=='*'&&(i==1||(i>=2&&f[0][i-1])))
{
f[0][i+1] = true;
}
}
if(n>0&&p[1]=='*')
{
f[0][2] = true;
}
int ii,jj;
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
// cout<<"i="<<i<<"j="<<j<<endl;
ii = i+1;
jj = j+1;
// cout<<"here1"<<endl;
if(p[j]!='*')
{
if(p[j]=='.'||p[j]==s[i])
{
// cout<<"here2"<<endl;
f[ii][jj] = f[ii-1][jj-1];
// cout<<"here3"<<endl;
}
}
else
{
//cout<<"here3"<<endl;
if(f[ii][jj-2])
{
f[ii][jj] = true;
}
else
{
if((p[j-1]=='.'||p[j-1]==s[i])&&f[ii-1][jj])
{
f[ii][jj] = true;
}
}
}
}
}
// cout<<"here4"<<endl;
return f[m][n];
}
};
20 [表示数值的字符串]
class Solution {
public:
enum State {
STATE_INITIAL,
STATE_INT_SIGN,
STATE_INTEGER,
STATE_POINT,
STATE_POINT_WITHOUT_INT,
STATE_FRACTION,
STATE_EXP,
STATE_EXP_SIGN,
STATE_EXP_NUMBER,
STATE_END
};
enum CharType {
CHAR_NUMBER,
CHAR_EXP,
CHAR_POINT,
CHAR_SIGN,
CHAR_SPACE,
CHAR_ILLEGAL
};
CharType toCharType(char ch) {
if (ch >= '0' && ch <= '9') {
return CHAR_NUMBER;
} else if (ch == 'e' || ch == 'E') {
return CHAR_EXP;
} else if (ch == '.') {
return CHAR_POINT;
} else if (ch == '+' || ch == '-') {
return CHAR_SIGN;
} else if (ch == ' ') {
return CHAR_SPACE;
} else {
return CHAR_ILLEGAL;
}
}
bool isNumber(string s) {
unordered_map<State, unordered_map<CharType, State>> transfer{
{
STATE_INITIAL, {
{CHAR_SPACE, STATE_INITIAL},
{CHAR_NUMBER, STATE_INTEGER},
{CHAR_POINT, STATE_POINT_WITHOUT_INT},
{CHAR_SIGN, STATE_INT_SIGN}
}
}, {
STATE_INT_SIGN, {
{CHAR_NUMBER, STATE_INTEGER},
{CHAR_POINT, STATE_POINT_WITHOUT_INT}
}
}, {
STATE_INTEGER, {
{CHAR_NUMBER, STATE_INTEGER},
{CHAR_EXP, STATE_EXP},
{CHAR_POINT, STATE_POINT},
{CHAR_SPACE, STATE_END}
}
}, {
STATE_POINT, {
{CHAR_NUMBER, STATE_FRACTION},
{CHAR_EXP, STATE_EXP},
{CHAR_SPACE, STATE_END}
}
}, {
STATE_POINT_WITHOUT_INT, {
{CHAR_NUMBER, STATE_FRACTION}
}
}, {
STATE_FRACTION,
{
{CHAR_NUMBER, STATE_FRACTION},
{CHAR_EXP, STATE_EXP},
{CHAR_SPACE, STATE_END}
}
}, {
STATE_EXP,
{
{CHAR_NUMBER, STATE_EXP_NUMBER},
{CHAR_SIGN, STATE_EXP_SIGN}
}
}, {
STATE_EXP_SIGN, {
{CHAR_NUMBER, STATE_EXP_NUMBER}
}
}, {
STATE_EXP_NUMBER, {
{CHAR_NUMBER, STATE_EXP_NUMBER},
{CHAR_SPACE, STATE_END}
}
}, {
STATE_END, {
{CHAR_SPACE, STATE_END}
}
}
};
int len = s.length();
State st = STATE_INITIAL;
for (int i = 0; i < len; i++) {
CharType typ = toCharType(s[i]);
if (transfer[st].find(typ) == transfer[st].end()) {
return false;
} else {
st = transfer[st][typ];
}
}
return st == STATE_INTEGER || st == STATE_POINT || st == STATE_FRACTION || st == STATE_EXP_NUMBER || st == STATE_END;
}
};
21 [调整数组顺序使奇数位于偶数前面]
class Solution {
public:
vector<int> exchange(vector<int>& nums) {
vector<int> result,rest;
for(auto &it:nums)
{
if(it%2)
{
result.push_back(it);
}
else
{
rest.push_back(it);
}
}
for(auto &it:rest){result.push_back(it);};
return result;
}
};
22 [链表中倒数第 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) {
int count = 1;
auto cur = head;
while(1)
{
if(cur->next!=NULL)
{
count++;
cur = cur->next;
}
else
{
break;
}
}
int s = count+1-k;
cur = head;
for(int i=0;i<s-1;i++)
{
cur = cur->next;
}
return cur;
}
};
24 [反转链表]
/**
* 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) return NULL;
if(head->next==NULL) return head;
ListNode* cur = head;
ListNode* next = cur->next;
ListNode* last = NULL;
ListNode* nextNext=next->next;
while(1)
{
//cout<<cur->val<<endl;
cur->next = last;
if(next!=NULL)
next->next = cur;
//cout<<"cur"<<cur->val<<"next"<<next->val<<endl;//<<"last"<<last->val<<endl;
last = cur;
cur = next;
if(cur==NULL) break;
next = nextNext;
if(next!=NULL)
nextNext = next->next;
}
return last;
}
};
25 [合并两个排序的链表]
/**
* 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) return l2;
if(l2==NULL) return l1;
ListNode* head = new ListNode;
ListNode* cur1(head);
ListNode* cur2(head);
if(l1->val<l2->val)
{
head = l1;
cur1 = l1->next;
cur2 = l2;
}
else
{
head = l2;
cur2 = l2->next;
cur1 = l1;
}
auto cur = head;
while(1)
{
if(cur1==NULL)
{
cur->next=cur2;
return head;
}
if(cur2==NULL)
{
cur->next = cur1;
return head;
}
if(cur1->val<cur2->val)
{
cur->next = cur1;
cur1 = cur1->next;
cur = cur->next;
}
else
{
cur->next = cur2;
cur2 = cur2->next;
cur = cur->next;
}
}
return head;
}
};
26 [树的子结构]
/**
* 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 recursion(TreeNode* A, TreeNode* B) {
if(A==NULL&&B!=NULL) return false;
if(B==NULL) return true;
return (A->val==B->val)&&recursion(A->left,B->left)&&recursion(A->right,B->right);
};
bool isSubStructure(TreeNode* A, TreeNode* B) {
//cout<<"A val"<<A->val<<" "<<"B val"<<B->val<<endl;
if(B==NULL) return false;
if(A==NULL) return false;
if(recursion(A,B)) return true;
if(isSubStructure(A->left,B)) return true;
if(isSubStructure(A->right,B)) return true;
return false;
};
};
27 [二叉树的镜像]
/**
* 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 root;
auto tmp = root->left;
root->left = root->right;
root->right = tmp;
mirrorTree(root->left);
mirrorTree(root->right);
return root;
}
};
28 [对称的二叉树]
/**
* 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 isSym(TreeNode* left,TreeNode* right)
{
if(left==NULL&&right==NULL) return true;
if(left==NULL&&right!=NULL) return false;
if(left!=NULL&&right==NULL) return false;
return (left->val==right->val)&&isSym(left->left,right->right)&&isSym(left->right,right->left);
}
bool isSymmetric(TreeNode* root) {
if(root==NULL) return true;
auto left = root->left;
auto right = root->right;
return isSym(left,right);
}
};
29 [顺时针打印矩阵]
class Solution {
vector<vector<int>> matrixG;
vector<int> result;
public:
void printSq(int i,int len1,int len2)
{
if(len1==1)
{
for(int s=i;s<=i+len2-1;s++)
{
result.push_back(matrixG[i][s]);
}
return;
}
if(len2==1)
{
for(int s=i;s<=i+len1-1;s++)
{
result.push_back(matrixG[s][i]);
}
return;
}
int n1 = i+len1-1;
int n2 = i+len2-1;
for(int k=i;k<=n2-1;k++)
{
//cout<<matrixG[i][k]<<endl;
result.push_back(matrixG[i][k]);
}
for(int k=i;k<=n1-1;k++)
{
//cout<<matrixG[k][n]<<endl;
result.push_back(matrixG[k][n2]);
}
for(int k=n2;k>i;k--)
{
//cout<<matrixG[n-1][k]<<endl;
result.push_back(matrixG[n1][k]);
}
for(int k=n1;k>i;k--)
{
//cout<<matrixG[k][i]<<endl;
result.push_back(matrixG[k][i]);
}
}
vector<int> spiralOrder(vector<vector<int>>& matrix) {
matrixG = matrix;
int len1,len2;
int size1 = matrix.size();
if(size1==0) return result;
int size2 = matrix[0].size();
for(int i=0;i<round(min(size1,size2)/2.0);i++)
{
len1 = size1-2*(i);
len2 = size2-2*(i);
printSq(i,len1,len2);
}
return result;
}
};
30 [包含 min 函数的栈]
class MinStack {
stack<int> stk;
public:
/** initialize your data structure here. */
MinStack() {
}
void push(int x) {
stk.push(x);
}
void pop() {
stk.pop();
}
int top() {
return stk.top();
}
int min() {
int m = stk.top();
stack<int> tmp;
while(!stk.empty())
{
m = stk.top()<m?stk.top():m;
tmp.push(stk.top());
stk.pop();
}
while(!tmp.empty())
{
stk.push(tmp.top());
tmp.pop();
}
return m;
}
};
/**
* 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();
*/
class MinStack {
stack<int> stk;
stack<int> tmp;
public:
/** initialize your data structure here. */
MinStack() {
// cout<<0<<endl;
}
void push(int x) {
stk.push(x);
if(tmp.empty()||x<=tmp.top())
{
tmp.push(x);
}
// cout<<1<<endl;
}
void pop() {
if(stk.top()==tmp.top())
tmp.pop();
stk.pop();
// cout<<2<<endl;
}
int top() {
// cout<<3<<endl;
return stk.top();
}
int min() {
// cout<<4<<endl;
return tmp.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->min();
*/
31 [栈的压入、弹出序列]
class Solution {
public:
bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
if(popped.size()==0) return true;
stack<int> stk;
int ind = 0;
for(auto &it:pushed)
{
//cout<<it<<endl;
stk.push(it);
while(!stk.empty()&&stk.top()==popped[ind])
{
//cout<<stk.top()<<endl;
stk.pop();
ind++;
//cout<<ind<<endl;
if(ind==popped.size()) return true;
}
}
return false;
}
};
32-I [从上到下打印二叉树]
/**
* 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;
vector<TreeNode*> queue;
queue.push_back(root);
while(!queue.empty())
{
auto node = queue[0];
queue.erase(queue.begin());
res.push_back(node->val);
if(node->left!=NULL) queue.push_back(node->left);
if(node->right!=NULL) queue.push_back(node->right);
}
return res;
}
};
32-II [从上到下打印二叉树 II]
/**
* 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;
vector<int> layer;
vector<TreeNode*> F1;
vector<TreeNode*> F2;
F1.push_back(root);
while(!F1.empty())
{
for(auto& it:F1)
{
if(it==NULL) continue;
layer.push_back(it->val);
F2.push_back(it->left);
F2.push_back(it->right);
}
if(!layer.empty())
res.push_back(layer);
layer.clear();
F1.clear();
F1 = F2;
F2.clear();
}
return res;
}
};
32-III [从上到下打印二叉树 III]
/**
* 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;
vector<int> layer;
vector<TreeNode*> F1;
vector<TreeNode*> F2;
F1.push_back(root);
int i=0;
while(!F1.empty())
{
for(auto& it:F1)
{
if(it==NULL) continue;
layer.push_back(it->val);
F2.push_back(it->left);
F2.push_back(it->right);
}
if(!layer.empty())
{
if(i%2==1)
reverse(layer.begin(),layer.end());
res.push_back(layer);
}
layer.clear();
F1.clear();
F1 = F2;
F2.clear();
i++;
}
return res;
}
};
33 [二叉搜索树的后序遍历序列]
class Solution {
bool recursion(int i,int j,vector<int>& postorder)
{
if(i>=j) return true;
int p = i;
while(postorder[p]<postorder[j]) p++;
int m = p;
while(postorder[p]>postorder[j]) p++;
return p==j&&recursion(i,m-1,postorder)&&recursion(m,j-1,postorder);
}
public:
bool verifyPostorder(vector<int>& postorder) {
return recursion(0, postorder.size() - 1,postorder);
}
};
34 [二叉树中和为某一值的路径]
/**
* 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:
vector<vector<int>> result;
void dfs(TreeNode* root,int target,vector<int> res,int sum)
{
if(root==NULL) return;
sum+=root->val;
res.push_back(root->val);
if(root->left==NULL&&root->right==NULL&&sum==target)
{
//cout<<"sum"<<sum<<endl;//"root.val"<<root->val<<endl;
result.push_back(res);
return;
}
if(root->left==NULL&&root->right==NULL&&sum!=target)
{
return;
}
//cout<<"root.val"<<root->val<<endl;
dfs(root->left,target,res,sum);
dfs(root->right,target,res,sum);
return;
}
vector<vector<int>> pathSum(TreeNode* root, int target) {
vector<int> res;
int sum = 0;
dfs(root,target,res,sum);
return result;
}
};
35 [复杂链表的复制]
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
*/
class Solution {
unordered_map<Node*, Node*> cachedNode;
public:
Node* copyRandomList(Node* head) {
if(head==NULL) return NULL;
auto cur = head;
Node* vir = new Node(0);
Node* oldNode = vir;
while(1)
{
Node* newNode = new Node(cur->val);
cachedNode[cur] = newNode;
oldNode->next = newNode;
cur = cur->next;
oldNode = newNode;
if(cur==NULL) break;
}
auto head1 = vir->next;
cur = head1;
auto cur1 = head;
while(cur!=NULL)
{
cur->random = cachedNode[cur1->random];
cur = cur->next;
cur1 = cur1->next;
}
return head1;
}
};
36 [二叉搜索树与双向链表]
/*
// 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 {
private:
Node *pre, *head;
void dfs(Node* cur) {
if(cur == NULL) return;
dfs(cur->left);
if(pre != NULL) pre->right = cur;
else head = cur;
cur->left = pre;
pre = cur;
dfs(cur->right);
}
public:
Node* treeToDoublyList(Node* root) {
if(root == NULL) return NULL;
dfs(root);
head->left = pre;
pre->right = head;
return head;
}
};
37 [序列化二叉树]
/**
* 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:
void rserialize(TreeNode* root, string& str) {
if (root == NULL) {
str += "None,";
} else {
str += to_string(root->val) + ",";
rserialize(root->left, str);
rserialize(root->right, str);
}
}
TreeNode* rdeserialize(list<string>& dataArray) {
if (dataArray.front() == "None") {
dataArray.erase(dataArray.begin());
return NULL;
}
TreeNode* root = new TreeNode(stoi(dataArray.front()));
dataArray.erase(dataArray.begin());
root->left = rdeserialize(dataArray);
root->right = rdeserialize(dataArray);
return root;
}
string serialize(TreeNode* root) {
string ret;
rserialize(root, ret);
cout<<ret<<endl;
return ret;
}
TreeNode* deserialize(string data) {
list<string> dataArray;
string str;
for (auto& ch : data) {
if (ch == ',') {
dataArray.push_back(str);
str.clear();
} else {
str.push_back(ch);
}
}
if (!str.empty()) {
dataArray.push_back(str);
str.clear();
}
return rdeserialize(dataArray);
}
};
// Your Codec object will be instantiated and called as such:
// Codec codec;
// codec.deserialize(codec.serialize(root));
38 [字符串的排列]
class Solution {
int size;
vector<string> result;
void recursion(string s,vector<bool> posUsed,string res)
{
if(res.size()==size)
{
result.push_back(res);
return;
}
for(int i=0;i<size;i++)
{
if(posUsed[i]) continue;
res.push_back(s[i]);
posUsed[i] = true;
recursion(s,posUsed,res);
posUsed[i] = false;
res.pop_back();
}
}
public:
vector<string> permutation(string s) {
size = s.size();
vector<bool> posUsed(size,false);
string res;
recursion(s,posUsed,res);
sort(result.begin(), result.end());
result.erase(unique(result.begin(), result.end()), result.end());
return result;
}
};
39 [数组中出现次数超过一半的数字]
方法一: 哈希表(时间 O ( n ) O(n) O(n),空间 O ( n ) O(n) O(n))
#include <iostream>
#include<vector>
#include<unordered_map>
using namespace std;
int main() {
vector<int> a = { 1,2,3,2,2,2,5,4,2 };
int n = a.size();
unordered_map<int, int> M;
for (int i = 0;i < n;i++)
{
M[a[i]]++;
}
for (auto& it : M)
{
if (it.second > n / 2)
{
cout << it.first << endl;
}
}
return 0;
}
方法二: 快速排序+剪枝(时间 O ( n ) O(n) O(n))
#include <iostream>
#include<vector>
using namespace std;
int swap(vector<int>& nums, int i, int j)
{
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
return 0;
}
int qsort(vector<int>& nums, int left, int right)
{
if (left >= right) return 0;
int std = nums[left];
int i = left;
int j = right;
while (1)
{
if (i >= j) break;
while (1)
{
if (j <= i || nums[j] < std) break;
j--;
}
while (1)
{
if (i >= j || nums[i] > std) break;
i++;
}
if (i < j) swap(nums, i, j);
}
int n = nums.size();
swap(nums, left, j);
if (abs(2 * j - n + 1) <= 1) return nums[j];
else if (j < n / 2) return qsort(nums, j + 1, right);
else return qsort(nums, left, j - 1);
return 0;
}
int main() {
vector<int> nums = { 1,2,3,2,2,2,5,4,2 };
int result = qsort(nums, 0, nums.size() - 1);
cout << result << endl;
return 0;
}
40 [最小的 k 个数]
class Solution {
public:
vector<int> getLeastNumbers(vector<int>& arr, int k) {
sort(arr.begin(),arr.end());
vector<int> r(k);
for(int i=0;i<k;i++)
{
r[i] = arr[i];
}
return r;
}
};
41 [数据流中的中位数]
class MedianFinder {
public:
/** initialize your data structure here. */
priority_queue<int,vector<int>,greater<int>> maxHeap;
priority_queue<int,vector<int>,less<int>> minHeap;
MedianFinder() {
}
void addNum(int num) {
if(maxHeap.size()==minHeap.size())
{
maxHeap.push(num);
minHeap.push(maxHeap.top());
maxHeap.pop();
}
else
{
minHeap.push(num);
maxHeap.push(minHeap.top());
minHeap.pop();
}
}
double findMedian() {
if(minHeap.size()==maxHeap.size())
{
return (maxHeap.top()+minHeap.top())/2.0;
}
else{
return minHeap.top();
}
}
};
/**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder* obj = new MedianFinder();
* obj->addNum(num);
* double param_2 = obj->findMedian();
*/
42 [连续子数组的最大和]
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int size = nums.size();
int m = nums[0];
for(int i=0;i<size;i++)
{
int s = 0;
for(int j=i;j<size;j++)
{
s+=nums[j];
m = max(m,s);
}
}
return m;
}
};
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int pre = 0, M = nums[0];
for (auto &it: nums) {
pre = max(pre + it, it);
M = max(M, pre);
}
return M;
}
};
43 [1 ~ n 整数中 1 出现的次数]
class Solution {
public:
int countDigitOne(int n) {
long long mulk = 1;
int ans = 0;
for (int k = 0; n >= mulk; ++k) {
ans += (n / (mulk * 10)) * mulk + min(max(n % (mulk * 10) - mulk + 1, 0LL), mulk);
mulk *= 10;
}
return ans;
}
};
44 [数字序列中某一位的数字]
class Solution {
public:
int findNthDigit(int n) {
if(n<10) return n;
int k=1;
n = n-10;
while(1)
{
k++;
if(n>=k*9*pow(10,k-1))
{
n-=k*9*pow(10,k-1);
}
else
{
break;
}
}
int p = n/k;
int d = n%k;
//cout<<"n="<<n<<"p="<<p<<"d="<<d<<endl;
int result = pow(10,k-1)+p;
result = result/pow(10,k-d-1);
result = result%10;
return result;
}
};
45 [把数组排成最小的数] 排序
class Solution {
public:
bool static cmp(string &x,string &y)
{
if(x+y<y+x) return true;
return false;
}
string minNumber(vector<int>& nums) {
vector<string> strs;
string res;
for(int i = 0; i < nums.size(); i++)
strs.push_back(to_string(nums[i]));//to_string 可以把数字常量包括小数转为字符串
sort(strs.begin(), strs.end(), cmp);
for(int i = 0; i < strs.size(); i++)
res.append(strs[i]);//可用 + 替代
return res;
}
};
46 [把数字翻译成字符串]
class Solution {
public:
int translateNum(int num) {
vector<int> nums;
while(1)
{
nums.push_back(num%10);
num = num/10;
if(num==0) break;
}
reverse(nums.begin(),nums.end());
int sz = nums.size();
vector<int> dp(sz+1);
dp[0] = 1;
dp[1] = 1;
for(int i=2;i<=sz;i++)
{
dp[i] = dp[i-1];
if(nums[i-2]==1||(nums[i-2]==2&&nums[i-1]<=5))
{
dp[i] +=dp[i-2];
}
}
return dp[sz];
}
};
47 [礼物的最大价值] 动态规划
class Solution {
public:
int maxValue(vector<vector<int>>& grid) {
int m = grid.size();
int n = grid[0].size();
vector<vector<int>> dp(m,vector<int>(n));
//dp[0][0] = grid[0][0];
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
if(i==0&&j==0)
{
dp[i][j] = grid[i][j];
}
else if(i==0)
{
dp[i][j] = dp[i][j-1]+grid[i][j];
}
else if(j==0)
{
dp[i][j] = dp[i-1][j] + grid[i][j];
}
else
{
dp[i][j] = max(dp[i-1][j],dp[i][j-1])+grid[i][j];
}
}
}
return dp[m-1][n-1];
}
};
48 [最长不含重复字符的子字符串]
class Solution {
public:
int lengthOfLongestSubstring(string s) {
if(s=="") return 0;
int sz = s.size();
vector<int> dp(sz);
dp[0] = 1;
int a = 0;
int M = 1;
for(int i=1;i<sz;i++)
{
int j;
for(j = i-1;j>=a;j--)
{
if(s[j]==s[i])
{
a = j;
dp[i] = i-j;
break;
}
//cout<<a<<" "<<j<<endl;
}
if(j<a)
{
//cout<<a<<" "<<j<<endl;
//cout<<dp[i]<<" "<<dp[i-1]<<endl;
dp[i] = dp[i-1]+1;
M = max(dp[i],M);
}
}
//for(auto &it:dp)
//{
// cout<<"dp="<<it<<endl;
//}
return M;
}
};
49 [丑数]
class Solution {
public:
int nthUglyNumber(int n) {
vector<int> dp(n+1);
dp[1] = 1;
int p1 = 1,p2 = 1,p3 = 1;
for(int i=2;i<=n;i++)
{
dp[i] = min(min(2*dp[p1],3*dp[p2]),5*dp[p3]);
if(dp[i]==2*dp[p1])
{
p1++;
}
if(dp[i]==3*dp[p2])
{
p2++;
}
if(dp[i]==5*dp[p3])
{
p3++;
}
}
return dp[n];
}
};
50 [第一个只出现一次的字符]
class Solution {
public:
char firstUniqChar(string s) {
unordered_map<char,int> map;
for(auto &it:s)
{
map[it]++;
}
for(auto &it:s)
{
if(map[it]==1)
{
return it;
}
}
return ' ';
}
};
51 [数组中的逆序对]
class Solution {
int result = 0;
int merge(vector<int> &nums,int left,int mid,int right)
{
//cout<<left<<" "<<mid<<" "<<right<<endl;
vector<int> L(nums.begin()+left,nums.begin()+mid+1);
vector<int> R(nums.begin()+mid+1,nums.begin()+right+1);
//cout<<"Li="<<L[0]<<endl;
//cout<<"Rj="<<R[0]<<endl;
int i=0;
int j=0;
int l1 = mid-left+1;
int l2 = right-mid;
int s=left;
//cout<<left<<" "<<mid<<" "<<right<<endl;
while(1)
{
if(i==l1)
{
//cout<<left<<" "<<mid<<" "<<right<<endl;
for(int k=j;k<l2;k++)
{
nums[s] = R[k];
s++;
}
return 0;
}
if(j==l2)
{
//cout<<left<<" "<<mid<<" "<<right<<endl;
for(int k=i;k<l1;k++)
{
nums[s] = L[k];
s++;
}
return 0;
}
if(L[i]<=R[j])
{
nums[s] = L[i];
i++;
}
else
{
//cout<<"here"<<endl;
nums[s] = R[j];
result+=l1-i;
j++;
}
s++;
//cout<<left<<" "<<mid<<" "<<right<<endl;
}
}
int mergeSort(int left,int right,vector<int> &nums)
{
if(left==right)
{
return 0;
}
int mid = (left+right)/2;
mergeSort(left,mid,nums);
mergeSort(mid+1,right,nums);
merge(nums,left,mid,right);
return 0;
}
public:
int reversePairs(vector<int>& nums) {
if(nums.empty()) return 0;
mergeSort(0,nums.size()-1,nums);
return result;
}
};
52 [两个链表的第一个公共节点] 链表
/**
* 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) {
unordered_map<ListNode*,int> map;
auto cur = headA;
while(cur!=NULL)
{
map[cur]++;
cur = cur->next;
}
cur = headB;
while(cur!=NULL)
{
if(map.find(cur)!=map.end())
{
return cur;
}
cur = cur->next;
}
return NULL;
}
};
53-I [在排序数组中查找数字 I]
class Solution {
public:
int search(vector<int>& nums, int target) {
unordered_map<int,int> map;
for(auto &it:nums)
{
map[it]++;
}
return map[target];
}
};
53-II [0 ~ n-1 中缺失的数字]
class Solution {
public:
int missingNumber(vector<int>& nums) {
for(int i=0;i<nums.size();i++)
{
if(nums[i]!=i)
{
return i;
}
}
return nums.size();
}
};
54 [二叉搜索树的第 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 {
vector<int> v;
void recursion(TreeNode* root)
{
if(root==NULL) return;
recursion(root->left);
v.push_back(root->val);
//cout<<root->val<<endl;
recursion(root->right);
}
public:
int kthLargest(TreeNode* root, int k) {
recursion(root);
return v[v.size()-k];
}
};
55-I [二叉树的深度]
/**
* 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 {
int depth;
void recursion(TreeNode* root,int d)
{
if(root==NULL)
{
//cout<<" "<<d<<endl;
depth = max(depth,d);
return;
}
//cout<<d<<endl;
//cout<<root->val<<endl;
recursion(root->left,d+1);
recursion(root->right,d+1);
return;
}
public:
int maxDepth(TreeNode* root) {
depth = 0;
int d = 0;
recursion(root,d);
return depth;
}
};
55-II [平衡二叉树]
/**
* 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 height(TreeNode* root) {
if (root == NULL) {
return 0;
} else {
return max(height(root->left), height(root->right)) + 1;
}
}
bool isBalanced(TreeNode* root) {
if (root == NULL) {
return true;
} else {
return abs(height(root->left) - height(root->right)) <= 1 && isBalanced(root->left) && isBalanced(root->right);
}
}
};
56-I [数组中数字出现的次数]
class Solution {
public:
vector<int> singleNumbers(vector<int>& nums) {
int r = 0;
for(auto &it:nums)
{
r = r^it;
}
vector<int> a;
vector<int> b;
int k = 0;
while(1)
{
if(r>>k&1) break;
k++;
}
for(auto &it:nums)
{
if(it>>k&1) a.push_back(it);
else b.push_back(it);
}
vector<int> result;
r = 0;
for(auto &it:a)
{
r = r^it;
}
result.push_back(r);
r = 0;
for(auto &it:b)
{
r = r^it;
}
result.push_back(r);
return result;
}
};
56-II [数组中数字出现的次数 II]
class Solution {
public:
int singleNumber(vector<int>& nums) {
unordered_map<int,int> map;
for(auto &it:nums)
{
map[it]++;
}
for(auto &it:map)
{
if(it.second==1)
{
return it.first;
}
}
return 0;
}
};
57 [和为 s 的两个数字]
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
int sz = nums.size();
int i = 0;
int j = sz-1;
int a,b;
while(1)
{
if(i==j) break;
a = nums[i];
b = nums[j];
if(a+b==target) break;
if(a+b>target)
{
j--;
continue;
}
if(a+b<target)
{
i++;
continue;
}
}
vector<int> result;
result.push_back(a);
result.push_back(b);
return result;
}
};
57-II [和为 s 的连续正数序列]
class Solution {
public:
vector<vector<int>> findContinuousSequence(int target) {
double sum;
vector<vector<int>> result;
vector<int> tmp;
for(int i=1;i<target;i++)
{
//sum = i;
for(int j=i+1;j<target;j++)
{
sum = (i+j)/2.0*(j-i+1);
//sum = sum+j;
if(sum>target) break;
//if(abs(sum-target)<0.1)
if(sum==target)
{
tmp.clear();
for(int k=i;k<=j;k++)
{
tmp.push_back(k);
}
result.push_back(tmp);
}
}
}
return result;
}
};
58-I [翻转单词顺序]
class Solution {
public:
string reverseWords(string s) {
s+=" ";//预处理
int n = s.size();
vector<string> res;
string tmp = "";
for(int i=0;i<n;i++)
{
if(s[i]==' ')
{
if(tmp.empty())
{
continue;
}
res.push_back(tmp);
tmp.clear();
}
else
{
tmp.push_back(s[i]);
}
}
reverse(res.begin(),res.end());
string result = "";
for(int i=0;i<res.size();i++)
{
result+=res[i];
if(i!=res.size()-1)
{
result+=" ";
}
}
return result;
}
};
58-II [左旋转字符串]
class Solution {
public:
string reverseLeftWords(string s, int n) {
string result = "";
int sz = s.size();
for(int i=n;i<sz;i++)
{
result.push_back(s[i]);
}
for(int i=0;i<n;i++)
{
result.push_back(s[i]);
}
return result;
}
};
59-I [滑动窗口的最大值]
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
if(nums.empty()) return {};
int n = nums.size();
priority_queue<pair<int, int>> q;//用 priority_queue 构造大顶堆,默认就是这个
for (int i = 0; i < k; ++i) {
q.emplace(nums[i], i);
}
vector<int> ans = {q.top().first};//最初窗口的最大值
for (int i = k; i < n; ++i) {//开始滑动
q.emplace(nums[i], i);
while (q.top().second <= i - k) {//最大值在窗口之前,就 pop 掉。
q.pop();
}
ans.push_back(q.top().first);
}
return ans;
}
};
59-II [队列的最大值]
class MaxQueue {
int q[20000];
int begin = 0, end = 0;
public:
MaxQueue() {
}
int max_value() {
int ans = -1;
for (int i = begin; i != end; ++i)
ans = max(ans, q[i]);
return ans;
}
void push_back(int value) {
q[end] = value;
end++;
}
int pop_front() {
if (begin == end)
return -1;
begin++;
return q[begin-1];
}
};
/**
* 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();
*/
60 [n 个骰子的点数]
class Solution {
public:
vector<double> dicesProbability(int n) {
vector<double> dp0(6,1.0/6);
for(int i=2;i<=n;i++)
{
vector<double> dp(5*i+1,0);
for(int j=1;j<=6;j++)
{
for(int k=0;k<dp0.size();k++)
{
dp[k+j-1] = dp[k+j-1]+1.0/6*dp0[k];
cout<<dp[k+j-1]<<endl;
}
}
//cout<<dp[5*i]<<endl;
dp0 = dp;
}
return dp0;
}
};
61 [扑克牌中的顺子]
class Solution {
public:
bool isStraight(vector<int>& nums) {
sort(nums.begin(),nums.end());
int num_zero = 0;
for(int i=0;i<nums.size();i++)
{
if(nums[i]==0)
{
num_zero++;
}
else
{
break;
}
}
//cout<<nums.size()<<endl;
//int s = 0;
for(int i=0;i<nums.size()-1;i++)
{
if(nums[i]==0) continue;
//cout<<nums[i+1]-nums[i]<<endl;
if(nums[i+1]==nums[i]) return false;
//sum+=nums[i+1]-nums[i];
}
int s = nums[nums.size()-1] - nums[num_zero];
if(nums.size()-1<s)
{
return false;
}
return true;
}
};
62 [圆圈中最后剩下的数字]
class Solution {
int recursion(int n,int m)
{
if(n==1)
{
return 0;
}
int r = (recursion(n-1,m)+m)%n;
return r;
}
public:
int lastRemaining(int n, int m) {
return recursion(n,m);
}
};
暴力解法超时如下:
class Solution {
public:
int lastRemaining(int n, int m) {
vector<int> a(n);
for(int i=0;i<n;i++)
{
a[i] = i;
}
int iter = -1;
for(int i=0;i<n-1;i++)
{
int j = 0;
while(1)
{
iter++;
iter = iter%n;
// cout<<iter<<" "<<j <<endl;
if(a[iter]!=-1)
{
j++;
}
if(j==m)
{
//cout<<a[iter]<<endl;
a[iter] = -1;
break;
}
}
}
int result;
for(auto &it:a)
{
if(it!=-1)
{
result = it;
break;
}
}
return result;
}
};
63 [股票的最大利润]
class Solution {
public:
int maxProfit(vector<int>& prices) {
int r = 0;
for(int i=0;i<prices.size();i++)
{
for(int j=i+1;j<prices.size();j++)
{
r = max(r,prices[j]-prices[i]);
}
}
return r;
}
};
64 [求 1+2+…+n]
class Solution {
public:
int sumNums(int n) {
n-1&&(n = n+sumNums(n-1));
return n;
}
};
65 [不用加减乘除做加法]
class Solution {
public:
int add(int a, int b) {
int c;
while(c!=0)
{
int n = a^b;
c = (unsigned)(a & b)<<1;
a = n;
b = c;
}
return a;
}
};
66 [构建乘积数组]
class Solution {
public:
vector<int> constructArr(vector<int>& a) {
if(a.empty()) return {};
int sz = a.size();
vector<int> B(sz);
vector<int> A(sz);
int s = 1;
int s1 = 1;
for(int i=sz-1;i>=0;i--)
{
s*=a[i];
B[i] = s;
s1 *= a[sz-1-i];
A[sz-1-i] = s1;
}
vector<int> result;
result.push_back(B[1]);
for(int i=1;i<sz-1;i++)
{
result.push_back(A[i-1]*B[i+1]);
}
result.push_back(A[sz-2]);
return result;
}
};
67 [把字符串转换成整数]
class Solution {
public:
int strToInt(string str) {
int flag=1;
int tmp;
long int result = 0;
bool begin = false;
for(int i=0;i<str.size();i++)
{
cout<<str[i]<<endl;
if(str[i]==' ')
{
if(begin==false)
{
continue;
}
else{
break;
}
}
else if(str[i]=='+')
{
if(begin==false)
{
flag = 1;
begin = true;
}
else{
break;
}
}
else if(str[i]=='-')
{
if(begin==false)
{
flag = -1;
begin = true;
}
else{
break;
}
}
else if(str[i]-'0'<=9&&str[i]-'0'>=0)
{
begin = true;
tmp = str[i] - '0';
result = result*10+tmp;
if(result<INT_MIN||result>INT_MAX)
{
if(flag>0)
{
return flag*INT_MAX;
}
else{
return INT_MIN;
}
}
//cout<<flag<<endl;
}
else{
break;
}
}
//cout<<str[str.size()-1]<<endl;
return flag*result;
}
};
68-I [二叉搜索树的最近公共祖先]
/**
* 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 {
TreeNode* recursion(TreeNode* root,int a,int b)
{
int value = root->val;
int m = min(a,b);
int M = max(a,b);
if(value>=m&&value<=M)
{
return root;
}
if(value<m)
{
return recursion(root->right,a,b);
}
else
{
return recursion(root->left,a,b);
}
}
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
return recursion(root,p->val,q->val);
}
};
68-II [二叉树的最近公共祖先]
/**
* 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* res;
bool recursion(TreeNode* root, TreeNode* p, TreeNode* q) {//判断以root为节点的数是否包含至少一个节点
if (root == NULL) return false;
bool lson = recursion(root->left, p, q);
bool rson = recursion(root->right, p, q);
if ((lson && rson) || ((root->val == p->val || root->val == q->val) && (lson || rson))) {
res = root;
} //递归的同时捕捉公共节点的情况
return lson || rson || (root->val == p->val || root->val == q->val);
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
recursion(root, p, q);
return res;
}
};
补充题
N皇后
class Solution {
vector<vector<string>> result;
vector<int> pos;
int nG;
int fresh( vector<vector<bool>> &M,int i,int j)
{
int sum = i+j;
int sub = i-j;
for(int i=0;i<nG;i++)
{
for(int j=0;j<nG;j++)
{
if(i+j==sum||i-j==sub)
{
M[i][j] = true;
}
}
}
return 0;
}
int pos2StrAndSave()
{
//vector<string> str(nG,"....");
string tmp(nG,'.');
vector<string> *str = new vector<string>(nG,tmp);
for(int i=0;i<nG;i++)
{
(*str)[i][pos[i]] = 'Q';
}
result.push_back(*str);
return 0;
}
int recursion(int m,vector<bool> colOccu,vector<vector<bool>> M)
{
if(m>=nG)
{
pos2StrAndSave();
return 0;
}
for(int j=0;j<nG;j++)
{
if(colOccu[j]) continue;
if(M[m][j]) continue;
pos[m]= j;
//cout<<m<<" "<<j<<endl;
auto M_back = M;
auto colOccu_back = colOccu;
colOccu[j] = true;
fresh(M,m,j);
recursion(m+1,colOccu,M);
M = M_back;
colOccu = colOccu_back;
}
return 0;
}
public:
vector<vector<string>> solveNQueens(int n) {
vector<bool> colOccu(n,false);
vector<vector<bool>> M(n,vector<bool>(n,false));
nG = n;
pos.resize(n);
recursion(0,colOccu,M);
return result;
}
};
快速排序
#include <iostream>
#include<vector>
#include<algorithm>
//#include<bits/stdc++.h>
using namespace std;
//i 从最左边元素(标兵)开始,j 从最右边元素开始
//j 找小于 std 的元素,i 找大于 std 的元素,j 先走(标兵在左,先走兵在右,平衡了)
//i==j 的时候,交换 std 与 j 的元素
//循环为 1+2 模式,一个循环内有两个循环,其一为右标兵移动,其二为左标兵移动
//其余问题代码写得很清楚,看代码
int swap(vector<int> &nums, int i, int j)
{
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
return 0;
}
int qsort(vector<int> &nums,int left,int right)
{
if (left >= right) return 0;//左边大等于右边,就返回,仅写 == ,对于两个元素的时候,不够鲁棒
int std = nums[left];
int i = left;//左边就是从标兵位置开始,这样两个元素的时候才不会出 bug
int j = right;
while (1)
{
if (i >= j) break;
while (1)//一定要右边先开始
{
if (j <= i || nums[j] < std)//左右指针相遇或者找到比标兵小的数就退出
{
break;
}
j--;
}
while (1)
{
if (i >= j || nums[i] > std)
{
break;
}
i++;
}
if (i < j)
{
swap(nums, i, j);
}
}
swap(nums, left, j);//跳出 i++ 和 j-- 之后再来交换
qsort(nums, left, j - 1);
qsort(nums, j + 1, right);
return 0;
}
int main() {
vector<int> nums = { 1,3,1,4,5,2,0 };
qsort(nums,0,nums.size()-1);
for (auto& it : nums)
{
cout << it << endl;
}
return 0;
}
486.预测赢家
class Solution {
public:
bool PredictTheWinner(vector<int>& nums) {
int n = nums.size();
vector<vector<int>> dp(n,vector<int>(n));
for(int i=0;i<n;i++)
{
dp[i][i] = nums[i];
}
for(int i=n-2;i>=0;i--)
{
for(int j=i+1;j<n;j++)
{
dp[i][j] = max(nums[i]-dp[i+1][j],nums[j]-dp[i][j-1]);
}
}
return dp[0][n-1]>=0;
}
};