牛客网剑指Offer题解C++ (1/10)

题目地址

一、二维数组中的查找

题目描述

在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

算法思想

首先在二维数组的第一行的数与这个整数比较,找到比这个整数大的位置的前一个位置,如果都比这个整数小,则这个位置就是第一行的最后一个位置。确定第一行的位置,就从这个位置往下找,如果找到就成功返回,找不到就把第一行确定的位置往前一个,再往下找,如果找到第一列没找到,就返回false。

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

二、替换空格

题目描述

请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。

算法思想

简单的题目,放了很久才拿起来,而且还是学习了别人的做法才会的,其实就是先统计空格的数量(count),才从后面往前遍历,遇到字幕往后移动 2 * count 位置,2 因为还有个空格,这样就刚好装下%20,遇到空格往后,将%20 填到字母前面。

class Solution {
public:
	void replaceSpace(char *str,int length) {
        int space = 0;
        for(int i = 0; i < length; i++) {
            if(*(str+i) == ' ') {
                space++;
            }
        }
        int pr = length - 1;
        while(length > 0 && pr > -1) {
            if(*(str + pr) == ' ') {
                *(str + pr + space * 2) = '0';
                *(str + pr + space * 2 - 1) = '2';
                *(str + pr + space * 2 - 2) = '%';
                space--;
            }
            else
                *(str + pr + space * 2) = *(str + pr);
            pr--;
        }
	}
};

三、从尾到头打印链表

题目描述

输入一个链表,从尾到头打印链表每个节点的值

算法思想

从头到尾将链表的值存到栈中,再一一从栈中取出。

class Solution {
public:
    vector<int> printListFromTailToHead(ListNode* head) {
        stack<int> S;
        vector<int> V;
        ListNode *p = head;
        while(p) {
            S.push(p->val);
            p = p->next;
        }
        while(!S.empty()) {
            int tmp = S.top();
            S.pop();
            V.push_back(tmp);
        }
        return V;
    }
};

四、重建二叉树

题目描述

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

算法思路

首先,将根结点的值找到,将前序的第一个找到在中序的位置(mid),这个中序的mid的左右便是根的左右子树,并且根据这个mid将中序分为两部分,分别为左右子树的中序遍历,并且将前序遍历也分为左右子树的前序遍历,再进行递归就行了,结束条件便是中序或者是前序的长度为0 了,返回NULL;

class Solution {
public:
    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
        TreeNode *root = (TreeNode *)malloc(sizeof(TreeNode));
        int mid = 0, j = 0, len = vin.size();
        
        if(len == 0)
            return NULL;
        
        vector<int> pre_left, pre_right, vin_left, vin_right;
        root->val = pre[0];
		for(; mid < len; mid++) {
			if(vin[mid] == pre[0])
				break;
		}

		while(j < mid) {
			vin_left.push_back(vin[j]);
			pre_left.push_back(pre[j+1]);
			j++;
		}
        
        j++;
        
		while(j < len) {
			vin_right.push_back(vin[j]);
			pre_right.push_back(pre[j]);
			j++;
		}
        
		root->left = reConstructBinaryTree(pre_left, vin_left);
		root->right = reConstructBinaryTree(pre_right, vin_right);
        return root;
    }
};

五、用两个栈实现队列

题目描述

用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

算法思想

进队列操作就用栈1进栈保存数据,出队列需要借助栈2,当栈2为空时,需要把栈1的数据出栈,将数据进栈到栈2,再将栈2出栈即为出队列,当栈2不为空时,栈2出栈的数据即为出队列数据。

class Solution
{
public:
    void push(int node) {
        stack1.push(node);
    }

    int pop() {
        if(stack2.empty()) {
            while(!stack1.empty()) {
                stack2.push(stack1.top());
                stack1.pop();
            }
            int t = stack2.top();
            stack2.pop();
            return t;
        }
        else {
            int t = stack2.top();
            stack2.pop();
            return t;
        }
    }

private:
    stack<int> stack1;
    stack<int> stack2;
};

六、旋转数组中的最小数字

题目描述

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。

算法描述

数组旋转前是非递减的,只要找到旋转后不是非递减的位置就是最小值。

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        int i = 1;
        while(i < rotateArray.size()) {
            if(rotateArray[i] < rotateArray[i-1])
                return rotateArray[i];
        	i++;
        }
        return 0;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值