您的位置:首页 > 编程语言 > C语言/C++

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

2018-01-29 22:27 218 查看

题目地址

一、二维数组中的查找

题目描述

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

算法思想

首先在二维数组的第一行的数与这个整数比较,找到比这个整数大的位置的前一个位置,如果都比这个整数小,则这个位置就是第一行的最后一个位置。确定第一行的位置,就从这个位置往下找,如果找到就成功返回,找不到就把第一行确定的位置往前一个,再往下找,如果找到第一列没找到,就返回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;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: