1.二维数组中的查找
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
解法1:有序数组想到二分查找,由于是二维数组,即进行多行的二分查找
bool Find(int target, vector<vector<int> > array){
if(array.size()==0){
return false;
}
for(int i=0;i<array.size();i++){
int low = 0,high = array[0].size()-1;
int mid;
while(low<=high){
mid = (low + high)/2;
if(array[i][mid]==target){
return true;
}
if(array[i][mid]<target){
low = mid + 1;
}else{
high = mid -1;
}
}
}
return false;
}
解法2:找到一个分界点,考虑4个点:左上、左下、右上、右下。左上角数值最小,向右和向下都是比它大的数,没有区分度,同理右下角也是,因此只能选择左下角或者右上角。
从左下角开始,只要比当前小的值,往上移,比当前值大的,往右移。
从右上角开始,只要比当前值小的,往下移,比当前值大的,往左移。
bool Find(int target, vector<vector<int> > array) {
//从[0,n-1]的位置开始查找
//> i++
//< j--
if(array.size()==0){
return false;
}
int height = array.size();
int width = array[0].size();
int i= 0,j=width-1;
while(i>=0&&j<width&&i<height&&j>=0){
if(array[i][j]==target){
return true;
}else if (array[i][j]>target){
j--;
}else{
i++;
}
}
return false;
}
2.替换空格 卡
3.从尾到头打印链表
思路1:从头到尾-->从尾到头 联想到栈,使用栈来记录节点
vector<int> printListFromTailToHead(ListNode* head) {
// 栈的特性
stack<ListNode *> s;
vector<int>res;
if(head==NULL){
return res;
}
ListNode *p = head;
while(p!=NULL){
s.push(p);
p = p->next;
}
while(!s.empty()){
int val = s.top()->val;
res.push_back(val);
s.pop();
}
return res;
}
思路2:先将链表进行遍历,记录节点个数,然后再重新遍历链表,数组下标位置移动从尾到头
vector<int> printListFromTailToHead(ListNode* head) {
// 先扫描一遍然后再填
int length = 0;
ListNode *p = head;
while(p!=NULL){
p = p->next;
length++;
}
vector<int> res(length);
int count = length-1;
p=head;
while(p!=NULL){
int t = p->val;
p = p->next;
res[count--] = t;
}
return res;
}
4.重建二叉树
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
TreeNode * bulid(vector<int> pre,int pre_begin,int pre_end,vector<int>post,int post_begin,int post_end)
递归左子树TreeNode * bulid(vector<int> pre,int pre_begin+1,int pre_begin+1+ left,vector<int>post,int post_begin,int post_begin+ left)
递归右子树TreeNode * bulid(vector<int> pre,int pos+1,int pre_end,vector<int>post,int pos+1,int post_end)
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
TreeNode *s = recon(pre,vin,0,pre.size()-1,0,pre.size()-1);
return s;
}
TreeNode* recon(vector<int> pre,vector<int> vin,int prel,int preh,int vinl,int vinh){
if(vinl==vinh){
TreeNode *s = new TreeNode (vin[vinl]);
cout<<"con "<<endl;
s->left = NULL;
s->right = NULL;
return s;
}
int r;
for(int i=vinl;i<=vinh;i++){
if(vin[i]==pre[prel]){
r = i;break;
}
}
TreeNode *s = new TreeNode (vin[r]);
s->left = NULL;
s->right = NULL;
if(r>vinl){
//cout<<pre[prel+1]<<pre[prel+(r-vinl)]<<endl;
s->left = recon(pre,vin,prel+1,prel+(r-vinl),vinl,r-1);
}
if(r<vinh){
//cout<<pre[prel+(r-vinl)+1]<<pre[preh]<<endl;
s->right = recon(pre,vin,prel+(r-vinl)+1,preh,r+1,vinh);
}
return s;
}
5.用两个栈实现队列
思路:栈1用来进栈,栈2用来出栈
进栈时可以直接进栈1,出栈时先判断栈2是否为空,若不为空,则栈2栈顶元素出栈,若为空,则判断栈1是否为空,若栈1为空,则退出,若不为空,则将栈1元素进栈到栈2再进行出栈。
class Solution
{
public:
void push(int node) {
stack1.push(node);
}
int pop() {
int res;
if(stack2.empty()&&stack1.empty()){
return -1;
}
if(!stack2.empty()){
res = stack2.top();
stack2.pop();
return res;
}
while(!stack1.empty()){
res = stack1.top();
stack1.pop();
stack2.push(res);
}
res = stack2.top();
stack2.pop();
return res;
}
private:
stack<int> stack1;
stack<int> stack2;
};
6.旋转数组的最小数字
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。