牛客網劍指offer刷題記錄(更新ing)

1.二維數組的查找

class Solution {
public:
    bool Find(int target, vector<vector<int> > array)
     {
         int leny=array.size();
         int lenx=array[0].size();
         int i,j;
    	 for(i=0,j=leny-1;i<lenx&&j>=0;)
    	 {    
	            if(target>array[i][j])
	            {
	                i++;
	            }
	            else
	            {
	                if(target<array[i][j])
	                {
	                    j--;
	                }
	                else if(target==array[i][j])
	                {
	                        return true;                    
	                }
	            }
	     }
    	 return false;
    }
};

2.替換空格

class Solution {
public:
	void replaceSpace(char *str,int length) 
	{
        int i=0;
        int count=0;        
        for(i=0;i<length;i++)      //統計空格數
        {
            if(str[i]==' ')
                count++;
        }        
        int length_new=length+2*count;     //新字符串的長度 
        //初始化
        int index_new=length_new-1;
        int index=length-1;
        for(;index>=0&&index_new>index;)
        {
            if(str[index]==' ')
            {
                //依次替換三個字符,修改索引偏差
                str[index_new]='0';
                str[index_new-1]='2';
                str[index_new-2]='%';
                index_new-=2;
            }
            else 
            {
                //複製字符
                str[index_new]=str[index];                
            }
            //索引-1
            index_new--;
            index--;
        }
	}
};

3.從尾到頭打印鏈表

/**
*  struct ListNode {
*        int val;
*        struct ListNode *next;
*        ListNode(int x) :
*              val(x), next(NULL) {
*        }
*  };
*/
class Solution {
public:
    vector<int> printListFromTailToHead(ListNode* head) {
        ListNode *p=head;
        vector<int> array_tmp;
        vector<int> array_result;
        while(p!=nullptr){
            array_tmp.push_back(p->val);
            p=p->next;
        }        
        while(array_tmp.size()>0)
        {
            array_result.push_back(array_tmp[array_tmp.size()-1]);
            array_tmp.pop_back();   //出棧
        }
        return array_result;
    }
};

4.重建二叉樹

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
        TreeNode* tree=new TreeNode(pre[0]);//根節點的值爲先序序列中的第0個
        int vin_root_index;//根節點在中序序列的索引
        int vec_left_length;//左子樹序列長度
        int vec_right_length;//右子樹序列長度
        vector<int> pre_left;//左子樹先序序列
        vector<int> pre_right;//右子樹先序序列
        vector<int> vin_left;//左子樹中序序列
        vector<int> vin_right;//右子樹中序序列
        for(int i=0;i<vin.size();i++)//求根節點在中序序列中的索引
        {
            if(vin[i]==pre[0])
            {
                vin_root_index=i;
            }
        }
        vec_left_length=vin_root_index;//中序序列中,根節點左邊的是左子樹的中序序列
        vec_right_length=vin.size()-vin_root_index-1;//中序序列中,根節點右邊的是右子樹的中序序列
        
        if(vec_left_length>0)//如果左子樹不爲空則添加左子樹
        {
            for(int i=0;i<vec_left_length;i++)
            {
               pre_left.push_back(pre[i+1]);
               vin_left.push_back(vin[i]);
            }
            tree->left=reConstructBinaryTree(pre_left,vin_left);
        }
        if(vec_right_length>0)//如果右子樹不爲空則添加右子樹
        {
            for(int i=0;i<vec_right_length;i++)
            {
               pre_right.push_back(pre[vin_root_index+1+i]);
               vin_right.push_back(vin[vin_root_index+1+i]);
            }
            tree->right=reConstructBinaryTree(pre_right,vin_right);
        }
        return tree;
    }
};

5.兩個棧實現隊列

class Solution
{
public:
    void push(int node) 
    {
        stack1.push(node);
    }
    int pop()
     {
            while(stack1.size()>0)
            {
	                stack2.push(stack1.top());
	                stack1.pop();
            }
            int value=stack2.top();
            stack2.pop();
            while(stack2.size()>0)
            {
	                stack1.push(stack2.top());
	                stack2.pop();
            }
            return value;
    }    
private:
    stack<int> stack1;
    stack<int> stack2;
};

6.旋轉數組的最小數字

class Solution {
public:
    //假設原數組爲[序列A,序列B],則旋轉後數組爲[序列B,序列A],序列A、B均滿足非遞減。
    //因此,序列B的末項>=序列A的首項,當且僅當 原數組的所有項都相同時取 “=”。當數組所有項都相同時,任意一項都是最小值。
    //排除序列B的末項=序列A的首項之後,當旋轉後數組 第i項的值<第i-1項的值,那麼第i項爲序列A的首項,第i-1項爲序列B的末項
    /*由於序列B中可能有連續幾項相同的數字,所以不能用尋找A的首項時不能用<=*/
     int minNumberInRotateArray(vector<int> rotateArray) {
        if(rotateArray.size()==0)
            return 0;
        for(int i=0;i<rotateArray.size();i++)
        {
            if(rotateArray[i]<rotateArray[i-1])
                return rotateArray[i];
        }
        return rotateArray[0];
    }
};

7.斐波那契數列

class Solution {
public:
    int Fibonacci(int n) {
        vector<int> arr;
        arr.push_back(0);
        arr.push_back(1);
        if(n>=2)
        {           
            for(int i=2;i<=n;i++)
                arr.push_back(arr[i-2]+arr[i-1]);
        }        
        return arr[n];
    }
    
};

8.跳臺階

class Solution {
public:
    int jumpFloor(int number) {
        vector<int> methodsToFloor;//跳上n級的方法有 methodsToFloor[n]種
        methodsToFloor.push_back(0);
        methodsToFloor.push_back(1);
        methodsToFloor.push_back(2);
        if(number>=3)
        {
            for(int i=3;i<=number;i++)
            methodsToFloor.push_back(methodsToFloor[i-1]+methodsToFloor[i-2]);
        }
        return methodsToFloor[number];
    }
};

9.變態跳臺階

class Solution {
public:
    int jumpFloorII(int number) {
        vector<int> methodsJumpN;//向上跳n級的方法有 methodsJumpN[n]種
        methodsJumpN.push_back(0);//0號序列數據無用,隨意填如一個數
        methodsJumpN.push_back(1);
        methodsJumpN.push_back(2);
        if(number>=3)
        {
            for(int i=3;i<=number;i++)
            {
                int methods=0;//step爲  向上跳i級的的方法種數
                for(int j=1;j<i;j++)//向上跳j級,再從j級一次跳上i   j可以是1,2,3,4,……,i-1級
                {
                    methods+=methodsJumpN[j]; 
                }
                methods++;//0級一次跳上i級;
                methodsJumpN.push_back(methods);
            }
        }
        return methodsJumpN[number];
    }
};

10.矩形覆蓋

class Solution {
public:
    int rectCover(int number) {
        vector<int> arr;
        arr.push_back(0);
        arr.push_back(1);
        arr.push_back(2);
        if(number>2)
        {
            for(int i=3;i<=number;i++)
             arr.push_back(arr[i-2]+arr[i-1]);// i-2的狀態加2塊橫着的模板,i-1的狀態加1塊豎着的模板  (i-1的情況中包含了i-2加一塊豎模板的情況)
        }
        return arr[number];
    }
   
};

11.二進制中1的個數

在這裏插入代碼片

12.數值的整數次方

class Solution {
public:
    double Power(double base, int exponent) {
        if(exponent<0)
        {
            return Power(1/base,-exponent);
        }
        if(exponent==0)
            return 1;
        if(exponent==1)
            return base;
        if(exponent%2==0)
            return Power(base,exponent/2)*Power(base,exponent/2);
        else
            return Power(base,exponent/2)*Power(base,exponent/2)*base;
    }
};

13.調整數組順序使奇數位於偶數前面

class Solution {
public:
    void reOrderArray(vector<int> &array) {
       vector<int> odd;//奇數序列
       vector<int> even;//偶數序列
       int len=array.size()-1;
       for(int i=len;i>=0;i--)
       {
           if(array[i]%2==0)
               even.push_back(array[i]);
           else
               odd.push_back(array[i]);
           array.pop_back();
       }
       while(odd.size()>0)
       {
           array.push_back(odd[odd.size()-1]);
           odd.pop_back();
       }
        while(even.size()>0)
        {
           array.push_back(even[even.size()-1]);
           even.pop_back();
       }
        
    }
};

14.鏈表中倒數第k個節點

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) 
    {
        int n=0;//統計鏈表總節點
        ListNode *pCur=pListHead;
        if(pCur==NULL)
            return pCur;
        while(pCur!=NULL){
            n++;
            pCur=pCur->next;
        }
        if(n<k){//如果k大於總結點數,返回空
            return NULL;
        }
        pCur=pListHead;
        for(int i=1;i<n-k+1;i++){//從第1個節點開始,找到倒數第k個節點
            pCur=pCur->next;
        }
        return pCur;
    }
};

15.反轉鏈表

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) 
    {
        ListNode *tmp=new ListNode(-1);
        ListNode *Cur,*Next;
        Cur=pHead;
        while(Cur!=nullptr){
            Next=Cur->next;
            Cur->next=tmp->next;
            tmp->next=Cur;
            Cur=Next;
        }
        return tmp->next;
    }
};

16.反轉鏈表

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        ListNode *tmp=new ListNode(-1);//指向被反轉部分的頭結點
        ListNode *Cur,*Next;//Cur指向當前被反轉節點,Next指向當前節點被反轉之前的後一個節點
        Cur=pHead;
        while(Cur!=nullptr){
            Next=Cur->next;
            Cur->next=tmp->next;
            tmp->next=Cur;
            Cur=Next;
        }
        return tmp->next;
    }
};

17.合併兩個排序的鏈表

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
    {
        //如果某個鏈表爲空,則餘下部分爲另外一個鏈表
        if(pHead1 == NULL)
            return pHead2;
        if(pHead2 == NULL)
            return pHead1;
        
        //遞歸,每次取出較小的節點作爲頭結點,指向下一次遞歸獲取的頭結點
        ListNode *head=nullptr;
        if(pHead1->val<=pHead2->val)
        {
            head=pHead1;
            head->next=Merge(pHead1->next,pHead2);
        }
        else
        {
            head=pHead2;
            head->next=Merge(pHead1,pHead2->next);
        }
        return head;
    }
};

18.樹的子結構

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
    bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
    {
        
        if(pRoot2==NULL){//B爲空,則不爲A的子結構
            return false;
        }
        if(pRoot1==NULL && pRoot2!=NULL){//A爲空,B不爲空,則B不是A的子結構
            return false;
        }
        
        if(pRoot1->val!=pRoot2->val){//當A的根節點與B的根節點不同,則判斷B是不是A的左子樹或者右子樹的子結構
            return HasSubtree(pRoot1->left,pRoot2)||HasSubtree(pRoot1->right,pRoot2);
        }
        
        if(pRoot2->left==NULL&&pRoot2->right==NULL){//當B的根與A的根相同,且B左右子樹都爲空,則B是A的子結構
           return true;
        }
        if(pRoot2->left==NULL&&pRoot2->right!=NULL){//當B的根與A的根相同,且B左子樹爲空,右子樹不爲空,如果 B的右子樹是A的右子樹的子結構,則B是A的子結構
            return HasSubtree(pRoot1->right,pRoot2->right);
        }
        if(pRoot2->left!=NULL&&pRoot2->right==NULL){//當B的根與A的根相同,且B右子樹爲空,左子樹不爲空,如果 B的左子樹是A的左子樹的子結構,則B是A的子結構
            return HasSubtree(pRoot1->left,pRoot2->left);
        }
        //當B的根與A的根相同,且B左右子樹均不爲空,則下列任意條件均滿足 B是A的子結構:①如果B的左子樹爲A的左子樹的子結構 且B的右子樹爲A的右子樹的子結構 ②B是A的左子樹的子結構 ③B是A的右子樹的子結構
        return HasSubtree(pRoot1->left,pRoot2->left)&&HasSubtree(pRoot1->right,pRoot2->right)||HasSubtree(pRoot1->left,pRoot2)||HasSubtree(pRoot1->right,pRoot2);
    }
};

19.二叉樹的鏡像

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
    void Mirror(TreeNode *pRoot) {
        if(pRoot==NULL)
            return;
        if(pRoot->left!=NULL||pRoot->right!=NULL){            
            TreeNode *temp;
            temp=pRoot->left;
            pRoot->left=pRoot->right;
            pRoot->right=temp;
        }
        Mirror(pRoot->left);
        Mirror(pRoot->right);
    }
    
};

20.順時針打印矩陣

class Solution {
public:
    vector<int> printMatrix(vector<vector<int> > matrix) {
        int col_step=matrix[0].size();
        int row_step=matrix.size();
        int col_local=-1;
        int row_local=0;
        vector<int> result;
        while(true){
            for(int i=0;i<col_step;i++){
                col_local++;
                result.push_back(matrix[row_local][col_local]);			
            }
            row_step--;
            if(row_step<=0){
                break;
            }

            for(int i=0;i<row_step;i++){
                row_local++;
                result.push_back(matrix[row_local][col_local]);

            }
            col_step--;
            if(col_step<=0){
                break;
            }


            for(int i=0;i<col_step;i++){
                col_local--;
                result.push_back(matrix[row_local][col_local]);

            }
            row_step--;
            if(row_step<=0){
                break;
            }

            for(int i=0;i<row_step;i++){
                row_local--;
                result.push_back(matrix[row_local][col_local]);

            }
            col_step--;
            if(col_step<=0){
                break;
            }
        }
        return result;
    }
};

21.包含min函數的棧

class Solution {
public:
    void push(int value) {
        data.push(value);
    }
    void pop() {
        data.pop();
    }
    int top() {
        return data.top();
    }
    int min() {
        int smin=data.top();
        stack_tmp.push(data.top());
        data.pop();
        while(!data.empty()){
            if(data.top()<smin){
                smin=data.top();
            }
            stack_tmp.push(data.top());
            data.pop();
        }
        while(!stack_tmp.empty()){
            data.push(stack_tmp.top());
            stack_tmp.pop();
        }
        return smin;
    }
private:
    stack<int> data;
    stack<int> stack_tmp;
};

22.棧的壓入、彈出序列

class Solution {
public:
    bool IsPopOrder(vector<int> pushV,vector<int> popV) {
        vector<int> tmp;
        int i=0,j=0;
        for(;i<pushV.size();i++){
            tmp.push_back(pushV[i]);
            for(;j<popV.size()&&tmp[tmp.size()-1]==popV[j];j++){
                tmp.pop_back();
            }
        }
        if(tmp.size()==0){
            return true;
        }
        return false;
    }
};

23.從上往下打印二叉樹

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
    vector<int> PrintFromTopToBottom(TreeNode* root) {
        queue<TreeNode*> list;
        vector<int> result;
        if(root==NULL){
            return result;
        }
        TreeNode * tmp;        
        list.push(root);
        while(!list.empty()){//隊列初始值爲根節點,每次循環輸出隊列第一個節點對應的值,並把第一個節點的葉子節點添加進隊列,然後把第一個節點彈出隊列
            tmp=list.front();
            result.push_back(tmp->val);
            if(tmp->left!=NULL){
                list.push(tmp->left);
            }
            if(tmp->right!=NULL){
                list.push(tmp->right);
            }
            list.pop();
        }
        return result;
    }
};

24.二叉搜索樹的後序遍歷序列

class Solution {
public:
    bool VerifySquenceOfBST_Mine(vector<int> sequence){
        int n=sequence.size();
        if(n==0||n==1){//若 子數組爲空或者1,則該子數組是後續後續二叉樹遍歷結果(原數組長度爲1也滿足此條件)
            return true;
        }
        int root=sequence[n-1];
        int left_end;
        vector<int> left,right;
        for(int i=0;i<n-1;i++){//從左到右把小於根的數壓入  左子數組,直到碰到大於根的數
            if(sequence[i]<root){
                left.push_back(sequence[i]);
            }
            else{
                left_end=i;
                break;
            }
        }
        for(int i=left_end+1;i<n-1;i++){  //從左子樹組的末端開始,把大於根的數壓入右子樹組,直到碰到根所在位置。若中途有不大於根的數,則數組不滿足條件。
            if(sequence[i]>root){
                right.push_back(sequence[i]);
            }
            else{
                if(i<n-2){
                    return false;
                }
            }
        }
        return VerifySquenceOfBST_Mine(left)&&VerifySquenceOfBST_Mine(right);//遞歸判斷左右子數組是否滿足條件
    }
    
    bool VerifySquenceOfBST(vector<int> sequence) {//原始數組爲空返回false,否則判斷是否爲後序遍歷結果。(區別於遞歸得出的空子數組的判斷結果)
        if(sequence.size()==0){
            return false;
        }
        else{
            return VerifySquenceOfBST_Mine(sequence);
        }        

    }
    
    
};

38.二叉樹的深度

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
    int TreeDepth(TreeNode* pRoot)
    {
        if(pRoot==NULL)//如果當前節點爲空,以當前節點爲根的二叉樹深度爲0
            return 0;
        /*節點不爲空,且有左子樹和右子樹時,
          如果左子樹深度較大,則以當前節點爲根的二叉樹深度爲 1+左子樹深度;
          如果右子樹深度較大,則以當前節點爲根的二叉樹深度爲 1+右子樹深度;*/
        return TreeDepth(pRoot->left)>TreeDepth(pRoot->right)?(1+TreeDepth(pRoot->left)):(1+TreeDepth(pRoot->right));
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章