剑指offer真题1--5

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

分析:因为这是一个有序的二维数组,且从左至右递增,从上至下递增,经过画图就会发现,再这个二维数组中有两个特殊的位置,左下角和右上角,这两个位置和其他地方不同,只有两条路径,分析起来更为简单,且两条路径的增长方向相反,更易比较

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;
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值