zoukankan      html  css  js  c++  java
  • 南大算法设计与分析课程课后习题(3)

    3.1

    不证明了

    3.2

    正确性不证了

    如果不进行优化,那最坏复杂度和平均复杂度都是n2

    冒泡排序代码如下:

    //冒泡排序
    void bubblesort(vector<int>& v) {
        for (int i = 0; i < v.size() - 1; ++i) {
            for (int j = 0; j < v.size() - i -1; ++j) {
                if (v[j] > v[j + 1]) {
                    swap(v[j], v[j + 1]);
                }
            }
        }
    }
    冒泡排序

    冒泡排序的一种优化方案:

    //冒泡排序改进1,加入变量记录是否交换
    void bubblesort1(vector<int>& v) {
        for (int i = 0; i < v.size() - 1; ++i) {
            bool right = true;
            for (int j = 0; j < v.size() - i - 1; ++j) {
                if (v[j] > v[j + 1]) {
                    right = false;
                    swap(v[j], v[j + 1]);
                }
            }
            if (right == true)
                return;
        }
    }
    冒泡排序改进1

    冒泡排序按书中3的方式进行优化:

    //冒泡排序改进2,加入变量记录每次循环中最后发生元素交换的位置
    //注意此处的写法,一定要每一个遍历周期对j的末位置进行一次替换,而不能直接使用last_swap_pos作为末位置
    void bubblesort2(vector<int>& v) {
        int last_swap_pos = v.size() - 1;
        for (int i = 0; i < v.size() - 1; ++i) {
            int last_pos = last_swap_pos;
            for (int j = 0; j < last_pos; ++j) {
                if (v[j] > v[j + 1]) {
                    last_swap_pos = j+1;
                    swap(v[j], v[j + 1]);
                }
            }
        }
    }
    冒泡排序改进2

    两种优化方案的最坏复杂程度都没有变,任然是n2

    如果要算平均复杂度,第一次要n的复杂度,第二次需要(n-1)/2次比较,第3次需要(n-2)/2,依次类推,求和得复杂度应该还是n2

    3.3

    煎饼排序问题,据说这个问题的作者是比尔盖茨

    • 当只有一个煎饼的时候很容易可以正确
    • 假设当有n个煎饼的时候成立,当有n+1个煎饼的时候,找到最大的煎饼,假设最大的煎饼在k处,从k处翻一下,可以使最大的煎饼冒到最上层,然后全部n+1个煎饼翻一下,则最大的煎饼处在最下层,接着使用已知结论,n个煎饼时成立,可以使上面n个煎饼有序,所以证明了n+1时成立。

    复杂度分析:首先遍历一遍找到最大的煎饼需要n的复杂度,最大的煎饼翻到最下层需要2次操作,类推一下,复杂度应该为n2

    3.4

    遍历到数n1时,查看前一个数n2,如果n2>n1,则n2处的结果应该为它的前项,否则查看结果数组result,使用n1去和result[n1]处的比较

    //pervious-larger
    vector<int> perviouslarger(vector<int>& v) {
        vector<int> result(v.size(),0);
        for (int i = 1; i < v.size(); ++i) {
            int pos = i - 1;
            while (v[result[pos]] < v[i]) {
                pos = result[result[pos]];
                if (pos == 0)
                    break;
            }
            result[i] = pos;
        }
        return result;
    }
    
    //这是测试用例
    int main()
    {
        vector<int> v = {4,2,1,6,3,9};
        auto result = perviouslarger(v);
        for (auto i : result) {
            cout << i << endl;
        }
    
        system("pause");
        return 0;
    }
    perviouslarger

     3.5

    这题就遍历一遍,把字符串分割成多个单词,加入到数组中,最后逆序输出就可以了吧。

    时间复杂度和空间复杂度都是n

    3.6

    应该是只能有一个吧

    暴力解法:遍历每个人的关注列表,找出一个都没有关注的人

    优化解法:选取其中任一人,依次询问他是否关注了其他人,得到他关注的人的列表,名人必定在这个列表之中,如果他都没有关注,那么他就是名人,然后对该列表中的每个人重复上述步骤,对每个列表取交集,不断缩小,直至列表只有一个人。

    3.7

    http://www.cnblogs.com/likaiming/p/8570205.html

  • 相关阅读:
    ubuntu上搭建review board代码评审站点
    android5.1 for tq335x
    2015.04.11
    DECLARE_GLOBAL_DATA_PTR宏定义问题
    6410移植android4.4.2笔记(持续更新)
    ubuntu安装packet提示重复冲突问题
    android5.0 aosp编译记录(由于机器硬件原因,改为4.4.2编译通过)
    2015.01.16
    2015.01.14
    SDSM框架
  • 原文地址:https://www.cnblogs.com/likaiming/p/8659062.html
Copyright © 2011-2022 走看看