zoukankan      html  css  js  c++  java
  • 剑指Offer面试题1

    面试题1:

    题目描述:

      如下为类型CMyString的声明,请为该类型添加赋值运算符函数。
        class CMyString
        {
        public:
          CMyString(char* pData = NULL);
          CMyString(const CMyString& str);
          ~CMyString(void);

        private:
          char* m_pData;
        }; 

    思路: 现代写法,传一个临时参数tmp,然后将tmp的m_pData值与this指针指向的值进行交换,就实现了运算符的重载。

      注:tmp出了作用域会自动调用析构函数释放,所以当tmp区域与this指向的为同一区域时,tmp释放,则this指针

      指向的区域也释放了,就会出现问题,所以需要加上条件(this!=&str)。

    代码:

    CMyString& CMyString::operator=(const CMyString& str)
    {
       if (this != &str)
       {
        CMyString temp(str);
    
        char* data = temp.m_pData;
        temp.m_pData = this->m_pData;
        this->m_pData = data;
        }
      return *this;
     }
     

    面试题3:

    题目描述:

      在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
    输入描述:
      array: 待查找的二维数组
      target:查找的数字
    输出描述:
      查找到返回true,查找不到返回false

    思路:从二维数组的左下角开始找,若当前位置比target小,则向右移;反之,向上移动。

    代码:

    class Solution 
    {
    public:
        bool Find(vector<vector<int> > array,int target)
        {
            
            int row =array.size();     //
            int col=array[0].size();   //
            int x=row-1;               //横坐标
            int y=0;                   //纵坐标
            while(x>=0 && y<col)
            {
                if(array[x][y]>target)      //当前位置值>target,上移
                    x--; 
                else if(array[x][y]<target) //当前位置值<target,右移
                    y++;
                else
                    return true;
            }
            return false;
        }
    };

    面试题4:

    题目描述:

      请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
     

    思路:先计算空格个数,str原长及新长度,然后从后向前拷贝,避免内存覆盖

    代码:

    //假定length为系统规定字符串输出的最大长度,固定为一个常数
    class Solution 
    {
    public:
        void replaceSpace(char *str,int length) 
        {
            if(str==NULL||length<0)//当str为空或最大长度非法,则返回
            {
                return;
            }
            int len=0;//str的长度
            int blank=0;//空格的个数
            int i=0;
            while(str[i]!='')
            {        
                if(str[i++]==' ')
                    blank++;
                len++;
            }
            int newlen=len+2*blank;//str替换后新的长度
            if(newlen>length)//新长度<系统分配的最大长度时,返回
                return;  
    
            //str的替换过程,从后向前拷贝
            while(len>=0 && newlen>len)
            {
                if(str[len]!=' ')
                   str[newlen--]=str[len];              
                 else
                 {
                   str[newlen--]='0';
                   str[newlen--]='2';    
                   str[newlen--]='%';    
                 }
                 len--;  
            } 
        }
    };

    面试题5:

    题目描述:

      输入一个链表,从尾到头打印链表每个节点的值。
    输入描述:
      输入为链表的表头
    输出描述:
      输出为需要打印的“新链表”的表头

    思路:递归,直至找到最后一个节点,进行打印。

    代码:

    /**
    *  struct ListNode {
    *        int val;
    *        struct ListNode *next;
    *        ListNode(int x) :
    *              val(x), next(NULL) {
    *        }
    *  };
    */
    class Solution {
    public:
        vector<int> printListFromTailToHead(struct ListNode* head) 
        {
            vector<int> tail;
            if(head!=NULL)
            {
                if(head->next!=NULL)
                    tail=printListFromTailToHead(head->next);
                tail.push_back(head->val);
            }
            return tail;
        }
    };

    面试题6:

    题目描述:

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

    思路:前序遍历的第一个节点为根节点root,再根据中序遍历的结果,查找到中序遍历结果中与root值相等的位置index,

      则该值左边的为左子树的节点,右边的为右子树的节点。然后以左、右子树为子问题,递归调用函数重建子树。

    代码:

    /**
     * Definition for binary tree
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
    public:
        struct TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> in) 
        {
            int Size = in.size();//遍历这棵树的节点数
            if(Size == 0)        //树为空 
                return NULL;
            vector<int> preLeft, preRight, inLeft, inRight;
            int val = pre[0];     //根节点的值(前序遍历的第一个值)
            TreeNode* node = new TreeNode(val);//构建根节点
            int index = 0;
            for(index = 0; index < Size; ++index)
            {
                if(in[index] == val) //在前序遍历结果中查找根节点值的位置
                    break;
            }
            for(int i = 0; i < Size; ++i)
            {
                if(i < index)//在中序遍历结果中,在根节点前的值均为二叉树的左子树的值
                {
                    //构建左子树
                    inLeft.push_back(in[i]);
                    preLeft.push_back(pre[i+1]);
                }
                else if(i > index)
                {
                    //构建右子树
                    inRight.push_back(in[i]);//Construct the right pre and in 
     
                    preRight.push_back(pre[i]);
                }
            }
            //分为子问题,递归调用
            node->left = reConstructBinaryTree(preLeft, inLeft);
            node->right = reConstructBinaryTree(preRight, inRight);
            return node;
        }
    };

    面试题7:

    题目描述:

        用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

    思路: 两个栈实现一个队列,记两个栈分别为stack1、stack2。入队列操作,即为入栈stack1操作;

        而出队列可先将stack1中的数据全部push到stack2中,两次先进后出,使得stack2中数据顺

        序就是队列先进先出的顺序,然后再将stack2的top数据pop即可。

        但须注意的是:将stack1中数据push到stack2之前,徐判断stack2是否为空:

              1)若为空,则将stack1中数据全部push进来后在pop它的top数据。

              2)若stack2中原本就有数据,则需先将stack2中原有的数据先pop

    代码:

    class Solution
    {
    public:
        void push(int node) //直接将数据入stack1,先进后出一次
        {
            stack1.push(node);        
        }
        int pop() 
        {
            if(stack2.empty())//若stack2为空,将stack1的数据全push进stack2中,先进后出二次(stcak2中的数据顺序为队列中的数据顺序)
            {
                while(!stack1.empty())
                {    
                    stack2.push(stack1.top());
                    stack1.pop();
                }
            }
            int top=stack2.top();//保存stack2的顶部数据
            stack2.pop();//将stack2中的顶部元素pop出去
            return top;
        }
    private:
        stack<int> stack1;
        stack<int> stack2;
    };
    
    
  • 相关阅读:
    JSP
    Map集合的四种遍历
    过滤器和监听器
    Web常用对象(2)
    Web常用对象(1)
    Java Web了解和Servlet初次见面
    面向对象之继承(1)
    SpringBoot使用简单缓存
    SpringBoot整合mybatis
    Spring Security 入门学习--数据库认证和授权
  • 原文地址:https://www.cnblogs.com/hanxiaoyu/p/5552688.html
Copyright © 2011-2022 走看看