美文网首页
斐波那契数列——jzoffer

斐波那契数列——jzoffer

作者: 二十岁的弹簧 | 来源:发表于2018-12-08 13:29 被阅读0次

    通常排序和查找是面试时考查算法的重点。重点掌握二分查找,归并排序和快速排序,做到随时正确、完整地写出它们的代码。

    # 二分查找(seq需要排好序的,假设是升序排列)
    def solution(seq, target):
        if len(seq) == 0:
            raise Exception("empty seq")
        found = False
        left = 0
        right = len(seq) - 1
        while left <= right:
            mid = (right - left) // 2
            if seq[mid] == target:
                found = True
                break
            elif seq[mid] > targrt:
                right = mid
            else:
                left = mid
        return found
    
    # 归并排序
    def solution(seq):
        if len(seq) <= 1:
            return seq
        left_index = 0
        right_index = len(seq) - 1
        mid = (right_index - left_index) // 2
        left = solution(seq[0: mid])
        right = solution(seq[mid:])
        ret = merge_func(left, right)
        return ret
    
    def merge_func(seq_a, seq_b):
        a = 0
        b = 0
        ret = []
        while a < len(seq_a) and b < len(seq_b):
            if seq_a[a] >= seq_b[b]:
                ret.append(seq_b[b])
                b += 1
            else:
                ret.append(seq_a[a])
                a += 1
        while a < len(seq_a):
            ret.append(seq_a[a])
            a += 1
        while b < len(seq_b):
            ret.append(seq_b[b])
            b += 1
        return ret
    
    # 快速排序
    def solution(seq):
        # 递归方法-pythonic,额外的存储空间成本
        if len(seq) <= 1:
            return seq
        pivot = seq[0]
        left = [i for i in seq[1:] if i < pivot]
        right = [i for i in seq[1:] if i >= pivot]
        return solution(left) + [pivot] + solution(right)
    # 快速排序,没有额外的存储空间
    def solution(seq, left, right):
        if left < right:
            pivot_index = get_pivot_index(seq, left, right)
            solution(seq, left, pivot_index)
            solution(seq, pivot_index+1, right)
    
    def get_pivot_index(seq, left, right):
        pivot_index = left
        pivot = seq[left]
        small = left + 1
        large = right - 1
        while small <= large:
            while pivot > seq[small] and small <= large:
                small += 1
            while pivot <= seq[large] and small <= large:
                large -= 1
            seq[small], seq[large] = seq[large], seq[small]
        seq[pivot_index], seq[large] = seq[large], seq[pivot_index]
        return large
    

    面试题如果要求在二维数组上搜索路径,我们可以尝试回溯法,通常回溯法很适合用递归的代码实现,如果限定不可以使用递归,考虑用栈来模拟递归的过程。

    面试题要求某个问题的最优解,并且该问题可以分为多个子问题,我们可以用动态规划。自上而下的递归思路会产生重复的计算,我们用自下而上的循环代码实现,把子问题的最优解先算出来并用数组(一般是一维或者二维数组)保存下来,接下来基于子问题的解计算大问题的解

    分解子问题的时候存在某个特殊的选择,如果采用这个特殊的选择将一定能得到最优解,该面试题可能适用于贪婪算法

    位运算是一种特殊的算法,它是把数字表示成二进制之后对0和1的操作。

    题目一:求斐波那契数列的第n项

    写一个函数,输入n,求斐波那契数列的第n项

    效率低的写法:

    def solution(n):
        if n < 0:
            return 0
        if n in (0, 1):
            return n
        else:
            return solution(n-1) + solution(n-2)
    

    上述方法的时间复杂度是以n的指数的方式递增的,原因是重复计算过多,自上而下的递归,解决方案:

    • 将计算结果存储到哈希表中,下次计算前先查找,查找到就不用重复计算

    • 自下而上的循环计算

      def solution(n):
          if n < 0:
              return 0
          if n in (0, 1):
              return n
          ret = 0
          first = 0
          second = 1
          for _ in range(2, n+1):
              ret = first + second
              first = second
              second = ret
          return ret
      

    相关文章

      网友评论

          本文标题:斐波那契数列——jzoffer

          本文链接:https://www.haomeiwen.com/subject/kcrqhqtx.html