剑指OFFER review 4-6题

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

思路:
已知二叉树的前序遍历和中序遍历便可以确定一颗二叉树。前序遍历vector的第一个元素作为二叉树的根结点,并利用该根结点把中序遍历vector划分为左右两颗子树,在前序遍历vector中找到对应的序列,迭代建立二叉树。

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
 class Solution {
public:
    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
    int value = pre[0];
    TreeNode *head = new TreeNode(value);
    int vinlen = vin.size()
    if(vinlen == 0)
        return NULL
    int i;
    for(i = 0; i < vinlen; i++)
    {
        if(vin[i] == value)
            break;
    }
    vector<int> pre_left, pre_right, vin_left, vin_right;
    for(int j = 0; j < i; j++)
    {
        vin_left.push_back(vin[i]);
        pre_left.push_back(pre[i+1]);
    }
    for(int j = i+1; j < vinlen; j++)
    {
        vin_right.push_back(vin[j]);
        pre_right.push_back(pre[j]);
    }
    head -> left = TreeNode* reConstructBinaryTree(pre_left, vin_left);
    head -> right = TreeNode* reConstructBinaryTree(pre_right,vin_right);
    return head;

注意 递归结束条件的理解:中序遍历vector的长度为0时,递归结束,返回NULL,程序末尾要返回头指针。

题目五:用两个栈实现队列
题目描述
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
思路:push的时候直接在栈1执行push操作;pop时,判断栈2是否为空,如果栈2空,则把栈1的元素pop出来,push到栈2,再pop,如果栈2非空,直接pop。

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

    int pop() {
        if(stack2.size() == 0)
        {
            while(!stack1.empty())
            {
                int value = stack1.top();
                stack2.push(value);
                stack1.pop();
            }
        }
        int tmp = stack2.top();
        stack2.pop();
        return tmp;

    }

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

第六题:旋转数组的最小元素
题目描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
思路:二分查找缩小查找空间,要考虑特殊情况。

#include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <algorithm>
using namespace std;
class Solution{
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
    int size = rotateArray.size()
    if(size == 0)
        return 0;
    int left = 0;
    int right = size - 1;
    int mid;
    while(rotateArray[left] >= rotateArray[right])
    {
        if(rotateArray[mid] == rotateArray[left]&& rotateArray[mid] == rotateArray[right])
            return minNumber(rotateArray,left,right)
        mid = (left + right)/2;
        if(right - left == 1)
        { 
            mid = right;
            break;
        }
        if(rotateArray[mid] >= rotateArray[left])
            left = mid;
        else right = mid;
    }
    return rotateArray[mid];
    }
private:
    int minNumber(vector<int> &rotateArray,int left, int right)
    {
        int min = rotateArray[left];
        for(nt i = left + 1; i <= right; i++)
        {
            if(rotateArray[i] < min)
                min = rotateArray[i];
        }
        return min;
    }
};

注意:可以遍历求最小值的方法做这道题,但时间复杂度为O(n)较大,考虑用二分查找降低时间复杂度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值