zoukankan      html  css  js  c++  java
  • 经典算法面试题

    1. 10亿个数中取前1000大的数

    维护一个1000个节点的小顶堆。

    时间复杂度O(nlogk)

    2. 合并k个有序(假设升序)数组

    具体步骤:(1)将k个数组的第一个元素取出来,维护一个小顶堆。

         (2)弹出堆顶元素存入结果数组中,并把该元素所在数组的下一个元素取出来压入队中。

         (3)调整堆的结构,使其满足小顶堆的定义。

         (4)重复(2)(3)直到合并完成。

    3. 给定一个正整数 N,需要把它分解成至少两个不同的整数和,问有多少种不同的分解方案

    动态规划:dp[n][m]表示n被分解为最大为m的数的方案数

    [dpleft[ n ight]left[ m ight] = sumlimits_{k = 1}^{m - 1} {dpleft[ {n - m} ight]left[ k ight]} ]

    4. 一个数组怎么输出前K大的值、时间复杂度。

    借助快排partition的思想,平均时间复杂度是O(n)

    5. 查找数组中出现次数超过一半的数字

    等价于求数组中第n/2大的数,和4中思想一样,平均时间复杂度O(n)

    6.二维数组查找(剑指offer)

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

    思路分析:我们注意到这个二维数组的行和列都是升序的,也就是说最上面的一行和最右边的一列在整体上也是升序的,在一个排序数组上查找某个我们会很自然的想起二分法。这样我们每次都把要查找的数和当前剩下的二维数组的右上角数字比较,这样每次我们都可以排除掉一行或一列。算法的时间复杂度是O(n+m),也就是行数加列数。

    7.数组中插入数字

    题一:替换空格(剑指offer)

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

    题二:两个排序数组A1和A2,现在想把A2插入A1中并仍保持有序。

    思路分析:数组是个顺序表,我们往数组中插入某个数的话必须要移动当前位置后面所有的数。常规的思路是每次插入一个数并移动后面的数,这样多次插入后会导致数组中有的数被移动了多次,极大浪费了效率。我们希望每个数移动一次就到达它最终的位置,所以我们往往会反向移动数组,这样做的好处是移动当前数时后面的数已经到达了最终位置,我们移动当前数不会影响到后面的数,这样就确保了每个数只被移动一次。

    8. 合并两个无序链表成一个有序链表,只能用常数空间。

    归并排序的思想,用快慢指针不断二分链表。

    9. 斐波那契数列高效计算

    斐波那契数列:f(0) = 0, f(1) = 1, f(n) = f(n - 1) + f(n - 2)

    方法一:递归,效率低

    方法二:循环,正着推

    方法三:矩阵运算

    10. 用A表示1第一列,B表示2第二列,。。。,Z表示26,AA表示27,AB表示28。。。以此类推。请写出一个函数,输入用字母表示的列号编码,输出它是第几列。

    解题思路:26进制转10进制。

     

    11. 输出一个整数二进制表示中1的个数

    解法1:右移原数判断,如果输入是负数可能陷入死循环。

    解法2:左移1

    解法3:把一个整数-1后与原数做与运算会消去原数最左边的1

    12. 最小方差划分

    把一个数组划分成两部分,使其方差和最小。

    D(X) = E(x^2) - [E(X)]^2

    迭代求和。

    13. 波兰式和逆波兰式相关问题

    计算(1+((2+3)*(4*5))),leetcode224

    14. 给定一个整数序列,你可以删去其中的连续一段(可以不删),求删去后数组的最大连续子段和。(招商银行M-Geeker竞赛)

    解题思路:最大连续子序列的变种题,从前往后遍历一遍求最大连续子序列和,然后从后往前遍历一遍求最大连续子序列和。

    思路拓展:对于删去中间一段不好直接操作的话,可以先从前往后遍历,在从后往前遍历。

    15. 小明要在t分钟之内做l张饼,有n个锅,但只能选其中k个锅,每个锅每分钟能做vi个饼,最多能做mi个饼,问能不能做完l张饼,如果能,输出最少需要多少分钟;如果不能,输出最多能做几张饼。

    解法: 先讨论能不能做完:每个锅在t分钟内能做的饼数为min(mi,vi*t), 降序排列,前k个锅能做出来的饼>l就能; 如果不能做完:直接输出前k个锅能做饼的和;如果能:二分最短时间,然后判断在mid分钟内能不能做完饼,判断方法同t分钟的情况。

    思路:查询时先想一下二分。

    16. O(1)时间删除链表指定节点(给定单向链表的头指针和一个节点指针)

    解题思路:把该节点下个节点的值复制到该节点,删除下个节点(注意该节点是尾节点和链表只有一个节点的特殊情况)

  • 相关阅读:
    rsync同步公网yum源搭建本地yum仓库
    为smokeping添加日志开启debug
    python中if __name__ == '__main__':的作用
    使用telnet访问百度
    RRDtool绘制lvs连接数图形
    HTML表格
    ip netns
    redis动态扩展内存
    route命令
    设置nginx日志滚动
  • 原文地址:https://www.cnblogs.com/xumaomao/p/11129815.html
Copyright © 2011-2022 走看看