剑指offer

剑指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 ' ';
    }
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值