问题与解释
- 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
/*
对于二位数组的长度获取,熟知size()用法。
因为是递增序列,对于有序序列可以使用二分查找。
如果使用循环遍历,在找到该值的之后,需要立马返回,节省性能。
注意,也许分为方阵和非方阵情况。
*/
//基本解,循环遍历
class Solution {
public:
bool Find(int target, vector<vector<int> > array) {
int row = array.size();
int col = array[0].size();
for (int i = 0; i < row; ++i) {
for (int j = 0; j < col; ++j) {
if (target == array[i][j])
return true;
}
}
return false;
}
};
//对角线法,通过对二维数组的有序规律,这个数的下方肯定比它大,这个数的左方肯定比它小,就有左下到右上的说法。
class Solution {
public:
bool Find(int target, vector<vector<int> > array) {
// array是二维数组,这里没做判空操作
int rows = array.size();
int cols = array[0].size();
int i=rows-1,j=0;//左下角元素坐标
while(i>=0 && j<cols){//使其不超出数组范围
if(target<array[i][j])
i--;//查找的元素较少,往上找
else if(target>array[i][j])
j++;//查找元素较大,往右找
else
return true;//找到
}
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+2*count]=str[i];
} else {
count--;
str[i+2*count]='%';
str[i+2*count+1]='2';
str[i+2*count+2]='0';
}
}
}
};
/*熟练使用C++特性*/
class Solution {
public:
void replaceSpace(char *str,int length) {
string s(str);
int 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(struct ListNode* head) {
vector<int> v;
while(head != NULL){
v.insert(v.begin(),head->val);//头插法
head = head->next;
}
return v;
}
};
class Solution {
public:
vector<int> printListFromTailToHead(struct ListNode* head) {
vector<int> tmp;
ListNode *pHead = head;
while(pHead != NULL){
tmp.push_back(pHead->val);
pHead = pHead->next;
}
vector<int> result(tmp.rbegin(),tmp.rend());//反序输出
return result;
}
};
/* 先递归展开,在后续收缩栈时,推入VECTOR的节点是逆序,函数调用也是一个栈。*/
class Solution {
public:
vector<int> printListFromTailToHead(struct ListNode* head) {
if(!head)
return vec;
printListFromTailToHead(head->next);
vec.push_back(head->val);
return vec;
}
private:
vector<int> vec;
};
class Solution {
public:
vector<int> printListFromTailToHead(struct ListNode* head) {
stack<int> a;
vector<int> b;
while(!head){
a.push(head->val);
head=head->next;
}
while(!a.empty()){
b.push_back(a.top());
a.pop();
}
return b;
}
};
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
/*
递归思想,每次将左右两颗子树当成新的子树进行处理,中序的左右子树索引很好找,前序的开始结束索引通过计算中序中左右子树的大小来计算,然后递归求解,直到startPre>endPre||startIn>endIn说明子树整理完到。方法每次返回左子树活右子树的根节点
*/
class Solution {
public:
TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin) {
TreeNode* root = reConstructBinaryT(pre, 0, pre.size()-1, vin, 0, vin.size()-1);
return root;
}
private:
TreeNode reConstructBinaryT(vector<int> &pre, int beginPre, int endPre, vector<int> &vin, int beginvin, int endvin) {
if (beginPre > endPre || beginVin > endVin)
return NULL;
TreeNode* root = new TreeNode(pre[beginPre])
for (int i = beginvin; i<=endvin; ++i) {
if (vin[i] == pre[beginPre]) {
root->left = reConstructBinaryTree(pre, beginPre+1, beginPre+i-beginvin, vin, beginvin, i-1);
root->right = reConstructBinaryTree(pre, i-beginvin+beginPre+1, endPre, vin, i+1, endvin);
break;
}
}
return root;
}
};
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型
class Solution{
public:
void push(int node) {
stack1.push(node);
}
int pop() { //等待栈2出完后才能继续入栈不然,不然就会占据栈顶
if(stack2.empty()){
while(!stack1.empty()){
stack2.push(stack1.top());
stack1.pop();
}
}
int t = stack2.top();
stack2.pop();
return t;
}
private:
stack<int> stack1;
stack<int> stack2;
};