zoukankan      html  css  js  c++  java
  • 剑指 offer 系列——数组中重复的数字

    面试题 4:数组中重复的数字

    题目一:找出数组中重复的数字

    在一个长度为 n 的数组里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意重复的数字。例如:如果输入长度为 7 的数组 {2, 3, 1, 0, 2, 5, 3},那么对应的输出是重复的数字 2 或者 3。

    思路:

    思路一:排序,然后再找出重复的数字。时间复杂度为 O(nlogn)。

    思路二:利用哈希表。先从头到尾按顺序扫描数组的每个数字,没扫描到一个数字的时候,都可以用 O(1) 的时间顺序来判断哈希表里是否已经包含了该数字。若没有,则加入哈希表;如有,则返回。这个算法的时间复杂度是 O(n)。

    思路三:观察下标。如果数组中没有重复的元素,重新排序后,数字 i 的下标位置为 i。但是出现了重复的,因此肯定不是 i。

    1. 重排数组后,依次扫描数组。
    2. 当扫描到下标为 i 时,首先比较这个数字的大小(用 m 表示)是不是等于 i。
    3. 若是,则接着扫描下一个数字;不是,则拿这个 m 与下标位置为 m 的数值进行比较。
    4. 如果相等,就找到了一个重复的数字;如果不等,则将这个数字 m (此数字的下标为 i) 与下表位置为 m 的进行交换。
    5. 接下来重复这个过程。

    上述思路的代码:

    ......(后续补充)

    本题考查点:

    • 对一位数组的理解和编程能力。
    • 考查应聘者的分析能力。

    题目二:不修改数组找出重复的数字。

    在一个长度为 n+1 的数组里的所有的数字都在 1~n 的范围内,所以数组中至少有一个数字是重复的。请找出数组中任意一个重复的数字,但是不能修改输入的数组。例如,如果输入长度为 8 的数组 {2, 3, 5, 4, 3, 2, 6, 7},那对应的输出是重复的数字 2 或者 3。

    思路:

    思路一:创建一个长度为 n+1  的辅助数组;然后逐一将数组中的每个数字复制到辅助数组中。如果原来的数字是 m,则将它复制到辅助数组中下标为 m 的位置。这样比较容易的能发现哪些是重复的,但是由于需要创建一个数组,所以此方案需要 O(n) 的辅助空间。

    思路二:避免使用 O(n) 的辅助空间。假如没有重复的数字,在 1~n 的范围内只有 n 个数字。由于数组包含超过 n 个数字,所以一定重复。此时,可想象到二分法的思路。

    1. 先将数字从中间的数字 m 分为两个部分,前一半为 1~m,如果包含的数量超过了 m,那这一半的区间里一定包含重复的数字;否则另一半 m+1~n 的区间一定包含重复的数字。
    2. 可以继续将重复的区间一分为二。直到找到一个重复的数字。

    上述思路的代码:

    ......(后续补充)

    本题考察点:

    • 对二分查找算法的理解,并能快速的正确的实现二分查找算法的代码。
    • 考查应聘者的沟通能力。

    面试题 4:二维数组中的查找

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

    思路:

    1. 首先数组是从左到右依次递增,从上到下依次递增的,所以上边的数总是大于下边的,右边的总是大于左边的;
    2. 右上角或者左下角选取一个数(以右上角的数为例),会有三种情况产生。等于,大于,小于需要查找的数;
    3. 等于要查找的数,直接返回 true;
    4. 大于要查找的数,要查找的数肯定在右上角的数的左边,因此,可以剔除右上角数所在的这一列;
    5. 如果小于要查找的数,则要查找的数肯定在右上角的数的下方,因此可以剔除右上角所在行的这一行;
    6. 循环下去,直到找到该数为止。

    上述的代码:

    ......(后续补充)

    本题考察点:

    • 对二维数组的理解及编程能力。二维数组在内存中占据连续的空间,在内存中从上到下存储各行元素,在同一行中按照从左到右的顺序存储。因此我们可以根据行号和列好计算出相对于数组首地址的偏移量,从而找到相对应的元素。
    • 考查分析问题的能力。当遇到比较复杂的问题时,能否通过具体的例子找出规律。这个题目只要从一个具体的二维数组的右上角开始分析,就能找到查找的规律,从而找到问题的突破口。
    作者:意无尽 公众号:意无尽 关于作者:本人目前传统专业,现自学 Java,后续会有向大数据方向转型。希望自己能一步一个脚印的走下去,以此博客来见证我技术的成长轨迹!
  • 相关阅读:
    如何用Django建立一个后台CRM系统02
    如何用Django建立一个后台CRM系统01
    多线程的UDP聊天器
    文件被导入时,能够直接执行的代码不需要被执行
    主动抛出异常
    python异常
    初始化动作只执行一次
    单例设计模式代码实现
    类的继承
    多态的案例演示
  • 原文地址:https://www.cnblogs.com/reformdai/p/11116655.html
Copyright © 2011-2022 走看看