zoukankan      html  css  js  c++  java
  • 【斯坦福算法分析和设计】作业1(附视频)


    视频封面
     

    附上一个视频,如何理解一个算法:

    https://www.bilibili.com/video/BV1iZ4y1W7ep

    选择题

    Q1

    题目

    3-way-MergeSort: 假设不将 MergeSort 的每一步分成两半,而是分成三份,单独进行排序,最后将它们全部合并。 该算法的整体渐近运行时间是多少? (提示:请注意,合并步骤仍然可以在O(n)时间内实施。)

    解答

    Step 1: 写下循环

    [公式] # 当n是1的时候排序是O(1)

    [公式]表示长度为n的数组的运行时间。而MergeSort将数组分成了三份,所以每份数组长度是[公式],而合并步骤可以在O(n)时间完成,所以整个的运行时间如下:

    [公式]

    Step 2: 假设 [公式],令[公式],因此我们有

    [公式] # 在k=0时

    [公式] # 把k和n的关系带入step1的公式2

    Step 3: 于是我们可以解决这个问题

    [公式]

    [公式]

    [公式]

    [公式]

    [公式] # 一直这样拆分

    [公式]

    [公式] # 去掉常数项

    [公式] # 把k根据上面的假设换成n

    [公式]

     

    Q2

    题目

    给你函数f和g,使得[公式]。 那么[公式]吗?(这里c是正常数。)你应该假定f和g非递减,并且始终大于1。

    解答

    根据大O的定义,存在正常数[公式][公式][公式]时,有

    [公式]

    让我们得出左侧的边界,我们有

    [公式]

    为了进一步简化,我们得到[公式],所以我们有

    [公式]

    [公式] 带入公式

    [公式] # 提取公共项

    [公式]

    [公式] # 使用g(n)非递减性质

    [公式]

    所以,存在正常数[公式][公式],当[公式]时,有[公式]

    于是[公式]

     

    Q3

    题目

    再次假设两个(正)非递减函数f和g,使得[公式]。 那么[公式]吗?

    解法

    不完全是,让我们来检查一些简单的特殊情况。

    情况1: f(n)=g(n)=n,这种情况下,2n=O(2n)是正确的。

    情况2: f(n)=10n,g(n)=n,这种情况下我们有[公式] # 课程2里面证明过,指数函数的指数和一个常数相乘改变了它的渐进性增长率。

    这样,我们可以确定:

    该说法并不总是正确的。

    该说法并非总是错误的。

    那么怎么让这种说法总是正确呢?

    根据大O的定义,存在正常数c和[公式],使得[公式]的时候,有[公式],就是说[公式],只需要让[公式]就好了。

     

    Q4

    题目

    k-way-MergeSort: 假设给定k个排序数组,每个数组包含n个元素,并且你想将它们组合成一个kn个元素的单个数组。 考虑以下方法:

    • 使用讲座中讲解的merge子程序,你可以合并前两个数组
    • 然后将第三个给定数组与前两个数组的合并版本合并
    • 然后将第四个给定数组与前三个数组的合并版本合并,依此类推
    • 直到合并到最后一个(kth)输入数组为止。

    将k,n作为输入,那么这个函数的运行时间是多少?

    解法

    为简单起见,我们说合并所需的时间仅等于列表长度的总和。(因为所有数组已经排好序了,只需要线性遍历它们)

    因此对于第一次合并,我们有[公式]

    对于第二次合并,我们有[公式]

    ...

    这些数字的总和为

    [公式]

     

    Q5

    题目

    [公式])。

    [公式]

    [公式]

    [公式]

    [公式]

    [公式]

    解法

    一个比较简单的方法是计算一堆值:

    很显然答案是这样的:

    [公式]

    实际上,我们再来看一下,取对数后(取对数不影响它们的渐进性),解决方案非常明显,所有的数取对数后

    [公式]

    亚线性排序,有 [公式]

    多项式排序,有 [公式]

    指数增长是最快的 [公式]

    所以排列顺序就出来了。

    编码题

    题目

    实现课堂上的逆序对计数。

    代码

    def count_inversions_and_sort(array1, array2):
        """
        :param array1: 已排序的数组1
        :param array2: 已排序的数组2
        :return: (逆序对个数,排序后的合并数组)
        """
        res = []
        split_inv = 0  # 存放逆序对个数
        i = 0
        j = 0
        l1 = len(array1)
        l2 = len(array2)
        num = l1 + l2  # 总的元素个数
    
        for _ in range(num):
            if i == l1:  # 数组1遍历完了,只需要把数组2的剩下元素加入数组中就行
                res += [array2[x] for x in range(j, l2)]
                break
            if j == l2:
                res += [array1[x] for x in range(i, l1)]
                break
    
            if array1[i] < array2[j]:  # 左边的数小
                res.append(array1[i])
                i += 1
            else:
                res.append(array2[j])  # 右边的数小
                j += 1
                split_inv += (l1 - i)  # l1中所有剩余的元素
    
        return (split_inv, res)
    
    
    def sort_and_count_inversions(array):
        """
        :param array: 需要排序的数组
        :return: (逆序对个数,排序后的数组)
        """
        if len(array) == 1:
            return (0, array)
    
        i = len(array) // 2  # 把数组分成左右两个部分
        l_inv, left = sort_and_count_inversions(array[0:i])  # 左逆序对
        r_inv, right = sort_and_count_inversions(array[i:])  # 右逆序对
        split_inv, merged = count_inversions_and_sort(left, right)  # 分离逆序对
    
        return (l_inv + r_inv + split_inv, merged)
  • 相关阅读:
    PAT (Advanced Level) Practice 1100 Mars Numbers (20分)
    PAT (Advanced Level) Practice 1107 Social Clusters (30分) (并查集)
    PAT (Advanced Level) Practice 1105 Spiral Matrix (25分)
    PAT (Advanced Level) Practice 1104 Sum of Number Segments (20分)
    PAT (Advanced Level) Practice 1111 Online Map (30分) (两次迪杰斯特拉混合)
    PAT (Advanced Level) Practice 1110 Complete Binary Tree (25分) (完全二叉树的判断+分享致命婴幼儿错误)
    PAT (Advanced Level) Practice 1109 Group Photo (25分)
    PAT (Advanced Level) Practice 1108 Finding Average (20分)
    P6225 [eJOI2019]异或橙子 树状数组 异或 位运算
    P4124 [CQOI2016]手机号码 数位DP
  • 原文地址:https://www.cnblogs.com/siguamatrix/p/12815072.html
Copyright © 2011-2022 走看看