文章目录
- 剑指offer03 数组中重复的数字
- 剑指offer04 二维数组中的查找
- 剑指offer05 替换空格
- 剑指offer06 从尾到头打印链表
- 剑指offer07 重建二叉树
- 剑指offer09 用两个栈实现队列
- 剑指offer10-I斐波那契数列
- 剑指offer10-II 青蛙跳台阶问题
- 剑指offer11 旋转数组中的最小数字
- 剑指offer12 矩阵中的路径
- 剑指offer13 机器人的运动范围
- 剑指offer14-I 剪绳子
- 剑指offer14 II 剪绳子II
- 剑指offer15 二进制中1的个数
- 剑指offer16 数值的整数次方
- 剑指offer17 打印从1到最大的n位数
- 剑指offer18 删除链表中的结点
- 剑指offer21 调整数组顺序使奇数位于偶数前面
- 剑指offer22 链表中倒数第k个节点
- 剑指offer24 反转链表
- 剑指offer25 合并两个排序的链表
- 剑指offer26 树的子结构
- 剑指offer27 二叉树的镜像
- 剑指offer28 对称的二叉树
- 剑指offer29 顺时针打印矩阵
- 剑指offer30 包含min函数的栈
- 剑指offer31 栈的压入、弹出序列
- 剑指offer32-I 从上到下打印二叉树
- 剑指offer32-II 从上到下打印二叉树
- 剑指offer32-III 从上到下打印二叉树
- 剑指offer33 二叉搜索树的后序遍历序列
- 剑指offer39 数组中出现次数超过一半的数字
- 剑指offer 50 第一个只出现一次的字符
剑指offer03 数组中重复的数字
//解法一
class Solution {
public:
int findRepeatNumber(vector<int>& nums) {
int len=nums.size();
int val;
sort(nums.begin(),nums.end());
for(int i=0;i<len;i++){
if(nums[i+1]==nums[i]){
val=nums[i];
break;
}
}
return val;
}
};
//解法二
class Solution {
public:
int findRepeatNumber(vector<int>& nums) {
int len=nums.size();
int val;
for(int i=0;i<len;i++){
while(nums[i]!=i){
if(nums[i]==nums[nums[i]]){
val=nums[i];
break;
}
int temp=nums[i];
nums[i]=nums[temp];
nums[temp]=temp;
}
}
return val;
}
};
剑指offer04 二维数组中的查找
//解法一 暴力
class Solution {
public:
bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
if(matrix.empty()){
return false;
}
int row=matrix.size();
int col=matrix[0].size();
for(int i=0;i<row;i++){
for(int j=0;j<col;j++){
if(matrix[i][j]==target){
return true;
}
}
}
return false;
}
};
//解法二
class Solution {
public:
bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
if(matrix.empty()){
return false;
}
int rows=matrix.size();
int cols=matrix[0].size();
int row=0;
int col=cols-1;
while(row<rows&&col>=0){
if(matrix[row][col]==target){
return true;
}
else if(matrix[row][col]>target){
col--;
}
else{
row++;
}
}
return false;
}
};
剑指offer05 替换空格
//解法一
class Solution {
public:
string replaceSpace(string s) {
string res;
for(int i=0;i<s.size();i++){
if(s[i]==' '){
res+="%20";
}
else{
res+=s[i];
}
}
return res;
}
};
//解法二
剑指offer06 从尾到头打印链表
/**
* 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) {
stack<int> st;
vector<int> vec;
while(head!=NULL){
st.push(head->val);
head=head->next;
}
while(!st.empty()){
int val=st.top();
vec.push_back(val);
st.pop();
}
return vec;
}
};
剑指offer07 重建二叉树
/**
* 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* buildTree(vector<int>& preorder, vector<int>& inorder) {
int len=preorder.size();
if(len==0){
return NULL;
}
vector<int> pre_left,pre_right,in_left,in_right;
TreeNode* root=new TreeNode(preorder[0]);
int gen;
for(int i=0;i<len;i++){
if(preorder[0]==inorder[i]){
gen=i;
break;
}
}
for(int i=0;i<gen;i++){
in_left.push_back(inorder[i]);
pre_left.push_back(preorder[i+1]);
}
for(int i=gen+1;i<len;i++){
in_right.push_back(inorder[i]);
pre_right.push_back(preorder[i]);
}
root->left=buildTree(pre_left,in_left);
root->right=buildTree(pre_right,in_right);
return root;
}
};
剑指offer09 用两个栈实现队列
class CQueue {
public:
CQueue() {
}
void appendTail(int value) {
s1.push(value);
}
int deleteHead() {
if(!s2.empty()){
int val=s2.top();
s2.pop();
return val;
}
if(s1.empty()){
return -1;
}
while(!s1.empty()){
s2.push(s1.top());
s1.pop();
}
int sval=s2.top();
s2.pop();
return sval;
}
stack<int> s1,s2;
};
/**
* Your CQueue object will be instantiated and called as such:
* CQueue* obj = new CQueue();
* obj->appendTail(value);
* int param_2 = obj->deleteHead();
*/
剑指offer10-I斐波那契数列
class Solution {
public:
int fib(int n) {
if(n==0){
return 0;
}
if(n==1){
return 1;
}
int dp[n+1];
dp[0]=0;
dp[1]=1;
for(int i=2;i<=n;i++){
dp[i]=(dp[i-1]+dp[i-2])%1000000007;
}
return dp[n];
}
};
剑指offer10-II 青蛙跳台阶问题
class Solution {
public:
int numWays(int n) {
if(n==0||n==1){
return 1;
}
if(n==2){
return 2;
}
int dp[101]={0};
dp[1]=1;
dp[2]=2;
for(int i=3;i<=n;i++){
dp[i]=(dp[i-1]+dp[i-2])%1000000007;
}
return dp[n];
}
};
//空间优化版本
class Solution {
public:
int numWays(int n) {
if(n==0||n==1){
return 1;
}
if(n==2){
return 2;
}
int val1=1,val2=2,val3;
for(int i=3;i<=n;i++){
val3=(val1+val2)%1000000007;
val1=val2;
val2=val3;
}
return val3;
}
};
剑指offer11 旋转数组中的最小数字
//解法一
class Solution {
public:
int minArray(vector<int>& numbers) {
int gen=0;
for(int i=0;i<numbers.size()-1;i++){
if(numbers[i]<=numbers[i+1]){
continue;
}
else{
gen=i+1;
}
}
if(gen==2){
return numbers[gen]<numbers[0]?numbers[gen]:numbers[0];
}
return numbers[gen];
}
};
剑指offer12 矩阵中的路径
class Solution {
public:
bool dfs(vector<vector<char>>& board,string& w,int i,int j,int k){
if(i>=board.size()||i<0||j>=board[0].size()||j<0||board[i][j]!=w[k]){
return false;
}
if(k==w.length()-1){
return true;
}
char temp=board[i][j];
board[i][j]='/';
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
for(int l=0;l<4;l++){
int m=i+dx[l];
int n=j+dy[l];
if(dfs(board,w,m,n,k+1)){
return true;
}
}
board[i][j]=temp;
return false;
}
bool exist(vector<vector<char>>& board, string word) {
for(int i=0;i<board.size();i++){
for(int j=0;j<board[0].size();j++){
if(dfs(board,word,i,j,0)){
return true;
}
}
}
return false;
}
};
剑指offer13 机器人的运动范围
//解法一
class Solution {
public:
int movingCount(int m, int n, int k) {
if(k==0){
return 1;
}
vector<vector<bool>> valid(m,vector<bool>(n,true));
return dfs(valid,m,n,0,0,k);
}
int dfs(vector<vector<bool>>& valid,int m,int n,int row,int col,int k){
int sum=getsum(row)+getsum(col);
if(row>=m||col>=n||sum>k||!valid[row][col]){
return 0;
}
valid[row][col]=false;
return 1+dfs(valid,m,n,row+1,col,k)+dfs(valid,m,n,row,col+1,k);
}
int getsum(int num){
if(num<10){
return num;
}
int sum=0;
while(num!=0){
sum+=num%10;
num/=10;
}
return sum;
}
};
//解法二 根据krahets写的c++的dfs 版本
class Solution {
public:
int m,n,k;
int movingCount(int m, int n, int k) {
this->m=m;
this->n=n;
this->k=k;
vector<vector<bool>> visited(m,vector<bool>(n,true));
return dfs(0,0,0,0,visited);
}
int dfs(int i,int j,int s1,int s2,vector<vector<bool>>& visited){
if(i>=m||j>=n||s1+s2>k||!visited[i][j]){
return 0;
}
visited[i][j]=false;
return 1+dfs(i+1,j,(i+1)%10!=0?s1+1:s1-8,s2,visited)+dfs(i,j+1,s1,(j+1)%10!=0?s2+1:s2-8,visited);
}
};
//解法三 根据krahets写的c++的bfs版本
class Solution {
public:
class node{
public:
int i,j,s1,s2;
node(int a,int b,int c,int d):i(a),j(b),s1(c),s2(d){
}
};
int movingCount(int m, int n, int k) {
int res=0;
vector<vector<bool>> visited(m,vector<bool>(n,true));
queue<node> que;
que.push(node(0,0,0,0));
while(!que.empty()){
node cur=que.front();
int i=cur.i,j=cur.j,s1=cur.s1,s2=cur.s2;
que.pop();
if(i>=m||j>=n||k<s1+s2||!visited[i][j]){
continue;
}
visited[i][j]=false;
res++;
que.push(node(i+1,j,(i+1)%10!=0?s1+1:s1-8,s2));//可以更改为que.push({i+1,j,(i+1)%10!=0?s1+1:s1-8,s2});
que.push(node(i,j+1,s1,(j+1)%10!=0?s2+1:s2-8));
}
return res;
}
};
剑指offer14-I 剪绳子
//解法一 参考Krahets 数学推导
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;
}
};
//解法二 贪心
/*在最优解下考虑其中任意一段x可能的取值(n>1,m>1)
①若为2,则只能为2个1.
②若为3,则只能为2和1
③若为4,则2*2
④若x>=5,都有3*(x-3)>x.
⑤又如果含有3个以上的2,则2*2*2<3*3,所以最多只有两个2
综上所述,最优解只能被分解成3和2,且最多只能有两个。
观察可以发现,当n>=5时,我们应该尽可能多地剪出长度为3的绳子,这样会让乘积最大。
除了当绳子的长度为4时,我们不用剪出长度为3的绳子,因为3x1 < 2x2,我们应该剪出长度为2的。
所以可以用绳长n % 3(n >= 4,n=1,2,3拿出来做特例单独return),那么情况就会有三种:n % 3 = 0或1或2。
=0,说明n可以整除3,直接return pow(3, n / 3);
=1,说明应该把多出来的这个1,和最后一个3拼在一起形成一个4,然后剪一个2x2出来,再与前面的相乘,即return pow(3, (n/3)-1) * 4;
=2,说明最后多出来一个2,直接用前面的结果乘2,即return pow(3, n/3) * 2;
*/
class Solution {
public:
int cuttingRope(int n) {
if(n<=3){
return 1*(n-1);
}
int res=1;
if(n%3==2){
n-=2;
res*=2;
}
if(n%3==1){
n-=4;
res*=4;
}
while(n>0){
res*=3;
n-=3;
}
return res;
}
};
//解法三 动态规划
class Solution {
public:
int cuttingRope(int n) {
if(n<=3){
return n-1;
}
int* products=new int[n+1];
products[0]=0;
products[1]=1;
products[2]=2;
products[3]=3;
int max=0;
for(int i=4;i<=n;i++){
max=0;
for(int j=1;j<=i/2;j++){
int product=products[j]*products[i-j];
if(max<product){
max=product;
}
}
products[i]=max;
}
max=products[n];
delete[] products;
return max;
}
};
剑指offer14 II 剪绳子II
//解法一 参考Krahets 数学推导
class Solution {
public:
int cuttingRope(int n) {
if(n<=3){
return n-1;
}
int b=n%3,p=1000000007;
long rem=1,x=3;
for(int a = n / 3 - 1; a > 0; a /= 2) {
if(a % 2 == 1) rem = (rem * x) % p;
x = (x * x) % p;
}
if(b == 0) return (int)(rem * 3 % p);
if(b == 1) return (int)(rem * 4 % p);
return (int)(rem * 6 % p);
}
};
剑指offer15 二进制中1的个数
//解法一
class Solution {
public:
int hammingWeight(uint32_t n) {
int res=0;
while(n){
res+=n&1;
n>>=1;
}
return res;
}
};
//解法二
class Solution {
public:
int hammingWeight(uint32_t n) {
int res=0;
while(n){
res++;
n&=(n-1);
}
return res;
}
};
快速幂算法(全网最详细地带你从零开始一步一步优化)
快速幂+矩阵快速幂(总结+例题)
#include <iostream>
#include <cmath>
#include <time.h>
using namespace std;
long long normalPower(long long base, long long power) {
long long result = 1;
for (int i = 1; i <= power; i++) {
result = result * base;
result = result % 1000;
}
return result % 1000;
}
int main() {
clock_t start, finish;
//clock_t为CPU时钟计时单元数
long long base, power;
cin >> base >> power;
start = clock();
//clock()函数返回此时CPU时钟计时单元数
cout << normalPower(base, power) << endl;
finish = clock();
//clock()函数返回此时CPU时钟计时单元数
cout << "the time cost is" << double(finish - start) / CLOCKS_PER_SEC;
//finish与start的差值即为程序运行花费的CPU时钟单元数量,再除每秒CPU有多少个时钟单元,即为程序耗时
return 0;
}
#include <iostream>
#include <cmath>
#include <time.h>
using namespace std;
long long fastPower(long long base, long long power) {
long long result = 1;
while (power > 0) {
if (power % 2 == 0) {
//如果指数为偶数
power = power / 2;//把指数缩小为一半
base = base * base % 1000;//底数变大成原来的平方
} else {
//如果指数为奇数
power = power - 1;//把指数减去1,使其变成一个偶数
result = result * base % 1000;//此时记得要把指数为奇数时分离出来的底数的一次方收集好
power = power / 2;//此时指数为偶数,可以继续执行操作
base = base * base % 1000;
}
}
return result;
}
int main() {
clock_t start, finish;
//clock_t为CPU时钟计时单元数
long long base, power;
cin >> base >> power;
start = clock();
//clock()函数返回此时CPU时钟计时单元数
cout << fastPower(base, power) << endl;
finish = clock();
//clock()函数返回此时CPU时钟计时单元数
cout << "the time cost is" << double(finish - start) / CLOCKS_PER_SEC;
//finish与start的差值即为程序运行花费的CPU时钟单元数量,再除每秒CPU有多少个时钟单元,即为程序耗时
return 0;
}
剑指offer16 数值的整数次方
class Solution {
public:
double myPow(double x, int n) {
if(x==0){
return 0;
}
long b=n;
if(b<0){
x=1/x;
b=-b;
}
double res=1.0;
while(b>0){
if((b&1)==1){
res*=x;
}
b>>=1;
x*=x;
}
return res;
}
};
剑指offer17 打印从1到最大的n位数
//求返回 int 类型数组,相当于默认所有数字都在 int32 整型取值范围内,因此不考虑大数越界问题。
class Solution {
public:
vector<int> printNumbers(int n) {
vector<int> res;
if(n==0){
return res;
}
int maxn=pow(10,n);
for(int i=1;i<maxn;i++){
res.push_back(i);
}
return res;
}
};
//打印大数版本
#include<iostream>
#include<string.h>
using namespace std;
void printnumber(char* number);
bool increment(char* number);
void Print1ToMaxOfNDigits(int n){
if(n<=0){
return;
}
char* numbers=new char[n+1];
memset(numbers,'0',n);
numbers[n]='\0';
while(!increment(numbers)){
printnumber(numbers);
}
}
bool increment(char* number){
int nLength=strlen(number);
int nTakeOver=0;
bool isoverflow=false;
for(int i=nLength-1;i>=0;i--){
int nSum=number[i]-'0'+nTakeOver;
if(i==nLength-1){
nSum++;
}
if(nSum>=10){
if(i==0){
isoverflow=true;
}
else{
nSum-=10;
nTakeOver=1;
number[i]='0'+nSum;
}
}
else{
number[i]='0'+nSum;
break;
}
}
return isoverflow;
}
void printnumber(char* number){
bool isbeginning0=true;
int nLength=strlen(number);
for(int i=0;i<nLength;i++){
if(isbeginning0&&number[i]!='0'){
isbeginning0=false;
}
if(!isbeginning0){
cout<<number[i];
}
}
cout<<" ";
}
int main(){
int n;
cin>>n;
Print1ToMaxOfNDigits( n);
}
剑指offer18 删除链表中的结点
/**
* 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* pre=head;
ListNode* cur=head->next;
while(cur!=NULL&&cur->val!=val){
pre=cur;
cur=cur->next;
}
if(cur!=NULL){
pre->next=cur->next;
}
return head;
}
};
剑指offer21 调整数组顺序使奇数位于偶数前面
//解法一 头尾双指针
class Solution {
public:
vector<int> exchange(vector<int>& nums) {
int len=nums.size()-1;
int i=0,j=len;
while(i<j){
while(i<j&&(nums[i]&1)==1){
i++;
}
while(i<j&&(nums[j]&1)==0){
j--;
}
int temp=nums[i];
nums[i]=nums[j];
nums[j]=temp;
}
return nums;
}
};
//解法二 快慢指针
class Solution {
public:
vector<int> exchange(vector<int>& nums) {
int slow = 0,fast = 0;
while(fast<nums.size()){
if((nums[fast]&1)==1) swap(nums,slow++,fast);
fast++;
}
return nums;
}
void swap(vector<int>& nums,int a,int b){
int temp = nums[a];
nums[a] = nums[b];
nums[b] =temp;
return;
}
};
剑指offer22 链表中倒数第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 len=0;
ListNode* cur=head;
while(head!=NULL){
len++;
head=head->next;
}
int i=1;
while(i!=len-k+1){
cur=cur->next;
i++;
}
return cur;
}
};
//解法二 双指针
/**
* 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* former=head,*latter=head;
for(int i=0;i<k;i++){
former=former->next;
}
while(former!=NULL){
former=former->next;
latter=latter->next;
}
return latter;
}
};
剑指offer24 反转链表
/**
* 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) {
ListNode* pre=NULL;
ListNode* cur=head;
if(head==NULL){
return head;
}
ListNode* pnext=head->next;
while(cur!=NULL){
cur->next=pre;
if(pnext==NULL){
return cur;
}
pre=cur;
cur=pnext;
pnext=pnext->next;
}
return cur;
}
};
剑指offer25 合并两个排序的链表
/**
* 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) {
ListNode* head=new ListNode(0);
ListNode* cur=head;
while(l1!=NULL&&l2!=NULL){
if(l1->val<l2->val){
cur->next=l1;
l1=l1->next;
}
else{
cur->next=l2;
l2=l2->next;
}
cur=cur->next;
}
if(l1!=NULL){
cur->next=l1;
}
else{
cur->next=l2;
}
return head->next;
}
};
剑指offer26 树的子结构
/**
* 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 isSubStructure(TreeNode* A, TreeNode* B) {
bool result=false;
if(A!=NULL&&B!=NULL){
if(A->val==B->val){
result=DoesTree1HaveTree2(A,B);
}
if(!result){
result=isSubStructure(A->left,B);
}
if(!result){
result=isSubStructure(A->right,B);
}
}
return result;
}
bool DoesTree1HaveTree2(TreeNode* A,TreeNode* B){
if(B==NULL){
return true;
}
if(A==NULL){
return false;
}
if(A->val!=B->val){
return false;
}
return DoesTree1HaveTree2(A->left,B->left)&&DoesTree1HaveTree2(A->right,B->right);
}
};
剑指offer27 二叉树的镜像
/**
* 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;
}
TreeNode* temp=root->left;
root->left=mirrorTree(root->right);
root->right=mirrorTree(temp);
return root;
}
};
剑指offer28 对称的二叉树
/**
* 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 isSymmetric(TreeNode* root) {
return isSymmetric(root,root);
}
bool isSymmetric(TreeNode* pRoot1,TreeNode* pRoot2){
if(pRoot1==NULL&&pRoot2==NULL){
return true;
}
if(pRoot1==NULL||pRoot2==NULL){
return false;
}
if(pRoot1->val!=pRoot2->val){
return false;
}
return isSymmetric(pRoot1->left,pRoot2->right)&&isSymmetric(pRoot1->right,pRoot2->left);
}
};
剑指offer29 顺时针打印矩阵
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
if(matrix.size()==0){
return {};
}
vector<int> res;
int l=0,r=matrix[0].size()-1,t=0,b=matrix.size()-1;
while(true){
for(int i=l;i<=r;i++){
res.push_back(matrix[t][i]);
}
if(++t>b){
break;
}
for(int i=t;i<=b;i++){
res.push_back(matrix[i][r]);
}
if(--r<l){
break;
}
for(int i=r;i>=l;i--){
res.push_back(matrix[b][i]);
}
if(--b<t){
break;
}
for(int i=b;i>=t;i--){
res.push_back(matrix[i][l]);
}
if(++l>r){
break;
}
}
return res;
}
};
剑指offer30 包含min函数的栈
//根据krahets写的cpp
class MinStack {
public:
/** initialize your data structure here. */
stack<int> s1,s2;
MinStack() {
}
void push(int x) {
s1.push(x);
if(s2.empty()||s2.top()>=x){
s2.push(x);
}
}
void pop() {
int val=s1.top();
s1.pop();
if(val==s2.top()){
s2.pop();
}
}
int top() {
return s1.top();
}
int min() {
return s2.top();
}
};
剑指offer31 栈的压入、弹出序列
class Solution {
public:
bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
stack<int> st;
int indexofpushed=0;
int indexofpoped=0;
while(indexofpushed<pushed.size()){
st.push(pushed[indexofpushed]);
indexofpushed++;
while(!st.empty()&&popped[indexofpoped]==st.top()){
st.pop();
indexofpoped++;
}
}
return indexofpoped==popped.size();
}
};
剑指offer32-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){
return res;
}
queue<TreeNode*> q;
q.push(root);
while(!q.empty()){
TreeNode* node=q.front();
q.pop();
res.push_back(node->val);
if(node->left){
q.push(node->left);
}
if(node->right){
q.push(node->right);
}
}
return res;
}
};
剑指offer32-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) {
if(root==NULL){
return vector<vector<int>>();
}
queue<TreeNode*> q;
q.push(root);
int cnt=0;
vector<vector<int>> res;
while(!q.empty()){
res.push_back({vector<int>()});
for(int i=q.size();i>0;i--){
TreeNode* node=q.front();
q.pop();
res[cnt].push_back(node->val);
if(node->left){
q.push(node->left);
}
if(node->right){
q.push(node->right);
}
}
cnt++;
}
return res;
}
};
剑指offer32-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) {
if(root==NULL){
return vector<vector<int>>();
}
deque<TreeNode*> d;
bool oddlevel=true;
int curlevelcount=1;
int nextlevelcount=0;
vector<vector<int>> res;
d.push_back(root);
while(!d.empty()){
vector<int> levlenumber;
if(oddlevel==true){
while(curlevelcount>0){
TreeNode* node=d.front();
d.pop_front();
levlenumber.push_back(node->val);
if(node->left){
d.push_back(node->left);
nextlevelcount++;
}
if(node->right){
d.push_back(node->right);
nextlevelcount++;
}
curlevelcount--;
}
}
else{
while(curlevelcount>0){
TreeNode* node=d.back();
d.pop_back();
levlenumber.push_back(node->val);
if(node->right){
d.push_front(node->right);
nextlevelcount++;
}
if(node->left){
d.push_front(node->left);
nextlevelcount++;
}
curlevelcount--;
}
}
oddlevel=!oddlevel;
curlevelcount=nextlevelcount;
res.push_back(levlenumber);
nextlevelcount=0;
}
return res;
}
};
剑指offer33 二叉搜索树的后序遍历序列
//方法一递归分治
class Solution {
public:
bool verifyPostorder(vector<int>& postorder) {
return recur(postorder,0,postorder.size()-1);
}
bool recur(vector<int>& postorder,int i,int j){
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&&recur(postorder,i,m-1)&&recur(postorder,m,j-1);
}
};
//解法二 参考数据结构和算法 、Krahets、失火的夏天
class Solution {
public:
bool verifyPostorder(vector<int>& postorder) {
stack<int> st;
int root=INT_MAX;
for(int i=postorder.size()-1;i>=0;i--){
int cur=postorder[i];
if(cur>root){
return false;
}
while(!st.empty()&&st.top()>cur){
root=st.top();
st.pop();
}
st.push(postorder[i]);
}
return true;
}
};
剑指offer39 数组中出现次数超过一半的数字
//解法一
class Solution {
public:
int majorityElement(vector<int>& nums) {
sort(nums.begin(),nums.end());
int i=nums.size()/2;
return nums[i];
}
};
//解法二
class Solution {
public:
int majorityElement(vector<int>& nums) {
int result=nums[0];
int times=1;
for(int i=1;i<nums.size();i++){
if(times==0){
result=nums[i];
times++;
}
else if(result==nums[i]){
times++;
}
else{
times--;
}
}
return result;
}
};
剑指offer 50 第一个只出现一次的字符
class Solution {
public:
char firstUniqChar(string s) {
if(s.size()==0){
return ' ';
}
map<char,int> ch;
int id=0,first=0;
while(id<s.size()){
ch[s[id]]++;
id++;
}
while(first<s.size()){
if(ch[s[first]]==1){
return s[first];
}
first++;
}
return ' ';
}
};