牛客网剑指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));
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章