剑指offer面试题笔记11~20题(Java实现)

一、面试题1:复制运算符函数(P24)

  题目:如下为类型CMString的声明,请为该类型添加赋值运算符函数。  

class CMyString

  {

  public:

  CMyString(Char* pData = NULL);

  CMyString(const CMyString& str);

  ~CMyString(void);

  private:

    char* m_pData;

  }

解题思路:

二、面试题2:实现Singleton模式(P31)

  题目:设计一个类,我们只能生成该类的一个实例。

解题思路:

三、面试题3:二维数组中的查找(P38)

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

解 题思路:根据二维数组的特点,从最后一列的第一个数字开始,若该数字大于那个整数,则该列中数字都大于该整数,因此可以排除该列。一直排除到某列第一个数 字小于该整数为止。从剩下的数组第一行的最后一个数字开始与整数进行比较,若该数字小于整数,表明该行中的数字都小于该整数,可以将该行排除,依此类推, 直到寻找到该整数为止。

public static boolean find(int[][] matrix, int rows, int columns, int number) {
        boolean found = false;
        if(matrix != null && rows >0 && columns >0) {
            int row = 0;
            int column = columns - 1;
            while (row < rows && column >= 0) {
                if (matrix[row][column] == number) {
                    found = true;
                    break;
                }
                else if (matrix[row][column] > number)
                    column -- ;
                else
                    row ++;
            }
        }

        return found;
    }

四、面试题4:替换空格(P44)

  题目:请实现一个函数,把字符串中的每个空格替换成“%20”。例如输入“We are happy.",则输出”We%20are%20happy."。

解题思路:若从前往后查找并替换,每替换一个空格,均需要将之后的字符向后移动,最后的“happy.”会移动两次。因此对含有O(n)个空格字符的字符串而言,总的时间效率是O(n2)。将从前往后替换变成从后往前替换,时间复杂度为O(n)。

解题思路:首 先遍历一次,统计出字符串中空格数n,则替换后字符串的长度为之前长度加2n。准备两个指针,P1和P2。1指向原字符串的末尾,2指向替换之后的字符串 的末尾。向前移动指针1,逐个将字符复制到2指向的位置,直到碰到第一个空格为止。将1前移一格,在2的前面插入字符串“%20”。继续循环该操作。

五、面试题5:从尾到头打印链表(P51)

  题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值。

  链表结点定义如下:  

struct ListNode

  {

    int m_nKey;

    ListNode* m_pNext;

  }

解题思路一:先进后出,可以用栈来实现这种顺序,每当经过一个结点,就将该节点放入栈中,遍历完整个链表后,从栈顶开始逐个输出结点的值。

public static Stack<ListNode> reverseList_2(ListNode node) {
        Stack stack = new Stack();
        while (node != null) {
            stack.push(node);
            node = node.next;
        }
        return stack;
    }

解题思路二:动态规划逐步将大问题拆解成小问题,当开始返回结果时,正好实现倒置功能。

public static ListNode reverseList_1(ListNode node) {
        if(node == null || node.next == null)
            return node;

        ListNode listNode = reverseList_1(node.next);
        node.next.next = node;
        node.next = null;
        return listNode;
    }

六、面试题6:重建二叉树(P55)

  题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

  二叉树结点的定义如下:  

struct BinaryTreeNode

  {

    int m_nValue;

    BinaryTreeNode* m_pLeft;

    BinaryTreeNode* m_pRight;

  }

解题思路:根据前序遍历找到根节点,在中序遍历中,在该根节点前的节点为该根节点的左子树,在该根节点后的节点为该根节点的右子树。采用递归的方法完成。

public static BinaryTreeNode construct(int[] preOrder,
                                            int beginP,
                                            int endP,
                                            int[] inOrder,
                                            int beginI,
                                            int endI) {
        if (beginP > endP || beginI > endI)
            return null;

        int rootData = preOrder[beginP];
        BinaryTreeNode head = new BinaryTreeNode();
        head.value = rootData;
        int divider = findIndexInArray(inOrder, rootData, beginI, endI);
        int offSet = divider - beginI - 1;
        BinaryTreeNode left = construct (preOrder, beginP + 1, beginP + 1 + offSet, inOrder, beginI, beginI + offSet);
        BinaryTreeNode right = construct (preOrder, beginP + offSet + 2, endP, inOrder, divider + 1, endI);
        head.left = left;
        head.right = right;
        return head;
    }

    public static int findIndexInArray(int[] a, int x, int begin, int end) {
        for (int i = begin; i <= end; i ++)
            if (a[i] == x)
                return i;
        return -1;
    }

    public static void preOrder(BinaryTreeNode n){
        if(n!=null){
            System.out.print(n.value+",");
            preOrder(n.left);
            preOrder(n.right);
        }
    }  

    public static void inOrder(BinaryTreeNode n){
        if(n!=null){
            inOrder(n.left);
            System.out.print(n.value+",");
            inOrder(n.right);
        }
    } 

    public static void afterOrder(BinaryTreeNode n){
        if(n!=null){
            afterOrder(n.left);
            afterOrder(n.right);
            System.out.print(n.value+",");
        }
    } 

七、面试题7:用两个栈实现队列(P59)

  题目:用两个栈实现一个队列。队列的声明如下:请实现它的两个函数appendTail和deleteHead,分别完成在队列尾部插入结点和在队列头部删除结点的功能。  

template<typename T> class CQueue

  {

  public:

    CQueue(void);

    ~CQueue(void);

    void appendTail(const T& node);

    T deleteHead();

  private:

    stack<T> stack1;

    stack<T> stack2;

  }

八、面试题8:旋转数组的最小数字(P66)

  题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。

解题思路:

九、面试题9:斐波那契数列(P73)

  题目一:写一个函数,输入n,求斐波那契数列的第n项。斐波那契数列的定义如下:

  

解题思路:

  题目二:一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

解题思路:

十、面试题10:二进制中1的个数(P78)

  题目:请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如把9表示成二进制是1001,有2位是1。因此如果输入9,该函数输出2。

解题思路:

时间: 2024-08-03 02:19:37

剑指offer面试题笔记11~20题(Java实现)的相关文章

二叉树层次遍历(剑指Offer面试题32:从上到下打印二叉树)

图1所示为二叉树的层次遍历,即按照箭头所指方向,按照1.2.3的层次顺序,对二叉树每个节点进行访问 (此图反映的是自左至右的层次遍历,自右至左的方式类似). 要进行层次遍历,需要建立一个队列.先将二叉树头节点入队列,然后出队列,访问该节点, 如果它有左子树,则将左子树的根结点入队:如果它有右子树,则将右子树的根结点入队.然后出队列,对出队节点访问, 如此反复直到队列为空为止. 1 import java.util.*; 2 class TreeNode 3 { 4 int val; 5 Tree

剑指offer面试题29:数组中出现次数超过一半的数字

题目:数组中有一个数字出现的次数超过数组长度的一般,请找出这个数字,例如输入一个长度为9的数组(1,2,3,2,2,2,5,4,2,).由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. 个人第一眼想法是通过一个sort函数,再判断中间那数出现次数,只要出现多于n/2,就直接输出. 一般来说,最为直观的算法面试官都不会满意,那么有没有更优的算法呢? 这种算法是受快速排序算法的启发.在随机快速排序算法中,我们现在数组中随机选择一个数字,然后调整数组中数字的顺序,使得比选中的数字小的数字

【剑指Offer面试题】二维数组中的查找

下决心AC所有剑指offer面试题. 九度OJ面试题地址:http://ac.jobdu.com/hhtproblems.php 书籍:何海涛--<剑指Offer:名企面试官精讲典型编程题> 对于面试题,面试官往往更希望我们能提出优化方法,这样更能体现我们的思维能力以及传说中的"内功".所以做剑指offer要着重训练这方面,多总结多细究,总是有好处的.加油~ 二维数组中的查找 时间限制:1 秒内存限制:32 兆 特殊判题:否提交:19005解决:3642 题目描述: 在一个

【剑指Offer面试题】九度OJ1384:二维数组中的查找

下决心AC全部剑指offer面试题. 九度OJ面试题地址:http://ac.jobdu.com/hhtproblems.php 书籍:何海涛--<剑指Offer:名企面试官精讲典型编程题> 对于面试题,面试官往往更希望我们能提出优化方法,这样更能体现我们的思维能力以及传说中的"内功".所以做剑指offer要着重训练这方面,多总结多细究,总是有优点的.加油~ 题目链接地址: http://ac.jobdu.com/problem.php?pid=1384 二维数组中的查找

【剑指Offer面试题】 九度OJ1516:调整数组顺序使奇数位于偶数前面

题目链接地址: http://ac.jobdu.com/problem.php?pid=1516 题目1516:调整数组顺序使奇数位于偶数前面 时间限制:1 秒内存限制:128 兆特殊判题:否提交:2858解决:924 题目描写叙述: 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得全部的奇数位于数组的前半部分,全部的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变. 输入: 每一个输入文件包括一组測试案例. 对于每一个測试案例.第一行输入一个n,代表该数组

【剑指Offer面试题】 九度OJ1386:旋转数组的最小数字

题目链接地址: http://ac.jobdu.com/problem.php?pid=1386 题目1386:旋转数组的最小数字 时间限制:1 秒内存限制:32 兆特殊判题:否提交:6914解决:1534 题目描述: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. 输入: 输入可能包含多个测试样例,对于每个测试案例, 输入的第一行为

剑指Offer 面试题36:数组中的逆序对及其变形(Leetcode 315. Count of Smaller Numbers After Self)题解

剑指Offer 面试题36:数组中的逆序对 题目:在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 例如, 在数组{7,5,6,4}中,一共存在5个逆序对,分别是(7,6),(7,5),(7,4),(6,4)和(5,4),输出5. 提交网址: http://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0ec6c5?tpId=13&tqId=11188 或 htt

[ 剑指offer ] 面试题8:二叉树的下一个节点

题目描述 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. 解题思路 1.找到所有的可能情况并归纳,写的代码需要把这些情况都覆盖到. 2.具体情况详见书本# -*- coding:utf-8 -*- # class TreeLinkNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = None # self

剑指offer 面试题8:旋转数组的最小数字 题解

面试题8:旋转数组的最小数字 题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个已从小到大排好序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为1.(要求不能直接遍历数组来求解.) 提交网址: http://www.nowcoder.com/practice/9f3231a991af4f55b95579b44b7a01ba?tpId=13&tqId=11159 或 http: