第一题:在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
分析:因为这是一个有序的二维数组,且从左至右递增,从上至下递增,经过画图就会发现,再这个二维数组中有两个特殊的位置,左下角和右上角,这两个位置和其他地方不同,只有两条路径,分析起来更为简单,且两条路径的增长方向相反,更易比较
class Solution {
public:
bool Find(int target, vector<vector<int> > array) {
int i=0;
int j=array[0].size()-1;
while(i<array.size()&&j>=0){
if(array[i][j]==target)
return true;
if(array[i][j]<target)
i++;
else if(array[i][j]>target)
j--;
}
return false;
}
};
第二题:请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy
分析:
法一:首先考虑的是插入这个字符串后,原字符串的字符下标全部都会改变,如果用从前往后遍历,用头插的话效率太低,所以用尾插,相当于先将后路铺好再来解决问题。
class Solution {
public:
void replaceSpace(char *str,int length) {
int count = 0;
for(int i = 0; i < length; ++i)
{
if(str[i] == ' ')
++count;
}
for(int i = length-1; i >= 0; --i)
{
if(str[i] != ' ')
{
str[i + count*2] = str[i];
}
else
{
--count;
str[i+count*2] = '%';
str[i+count*2+1] = '2';
str[i+count*2+2] = '0';
}
}
}
};
法二:调用string类的方法,直接可以完成这种操作(不过有时候编译可能不通过,也有点像作弊的感觉)
class Solution {
public:
void replaceSpace(char *str,int length) {
string s(str);
size_t i = 0;
while(i=s.find(' ',i))>-1)
{
s.erase(i, 1);
s.insert(i, "%20");
}
auto ret = s.c_str();
strcpy(str, ret);
}
};
第三题:输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。
分析:
法一:先入栈在出栈就欧克
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
vector<int> result;
while(head == nullptr)
return result;
stack<ListNode*> reverse;
ListNode* node = head;
while(node)
{
reverse.push(node);
node = node->next;
}
while(!reverse.empty())
{
node = reverse.top();
result.push_back(node->val);
reverse.pop();
}
return result;
}
};
法二:反向迭代器打印
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
vector<int> result;
if(head == nullptr)
return result;
ListNode* node = head;
while(node)
{
result.push_back(node->val);
node = node->next;
}
return (vector<int>(result.rbegin(), result.rend()));
}
};
第四题:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
分析:重建二叉树,必须要中序遍历的结果,先找到根节点,前序第一个元素就是根节点,然后在通过根节点找到中序遍历中根节点的位置,中序中根节点的左边的就是根节点的左子树,右边就是右子树,用归并排序即可重建二叉树
class Solution {
public:
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
int vinlen = vin.size();
if(vinlen == 0)
{
return nullptr;
}
TreeNode* head = new TreeNode(pre[0]);
vector<int> left_pre, left_vin, right_pre, right_vin;
int key = 0;
for(int i = 0; i < vinlen; ++i)
{
if(vin[i] == pre[0])
key = i;
}
for(int i = 0; i < key; ++i)
{
left_vin.push_back(vin[i]);
left_pre.push_back(pre[i+1]);
}
for(int i = key+1; i < vinlen; ++i)
{
right_vin.push_back(vin[i]);
right_pre.push_back(pre[i]);
}
head->left = reConstructBinaryTree(left_pre, left_vin);
head->right = reConstructBinaryTree(right_pre, right_vin);
return head;
}
};
第五题:用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型
分析:1.入栈:先判断B栈有没有数据,如果有数据,需要先出栈,因为必须保证B栈是空栈,然后再让A栈入栈;
2.出栈:先判断A栈有没有数据,如果有数据,需要先出栈,将数据全部压入B栈中,然后再让B栈出栈。
class Solution
{
public:
void push(int node) {
while(!stack2.empty())
{
stack1.push(stack2.top());
stack2.pop();
}
stack1.push(node);
}
int pop() {
while(!stack1.empty())
{
stack2.push(stack1.top());
stack1.pop();
}
int result = stack2.top();
stack2.pop();
return result;
}
private:
stack<int> stack1;
stack<int> stack2;
};