随笔 - 44,  文章 - 0,  评论 - 68

题目要求:

  • 01 有以下用Java语言描述的算法,说明其功能并计算复杂度,注意:时间结束后的回答无效

double fun(double y,double x,int n) { y=x; while (n>1) { y=y*x; n--; } return y; }

  • 02
  • 设 n 为正整数, 给出下列 3 个算法关于问题规模 n 的时间复杂度。
    (1) 算法 1
    void fun1(int n) { i=1,k=100; while (i<=n) { k=k+1; i+=2; } }

题目答案:

  • 01 O(n)

  • 功能为:

  • 在n大于1的时候,计算x的n的次方。while (n>1) { y=y*x; n--; }

  • 若n小于一,则返回x(因为y=x)return y;

  • 02

  • (1)O(n)

  • (2)O(n²)

  • (3)O(根号n)

答题思路:

  • 首先我参考了一下博客
  • 在看完这篇博客后,我一开始对于算法复杂度的理解是这样的:
  • 1.有一个循环算一个n,有两个循环就n*n,算法复杂度就是看多少个n相乘就是O(n)的多少次方。
  • 2.有一个if的时候,操作次数就除以2。
  • 但是我发现,我的想法好像和链接里面不是特别的一样?
  • 比如:
  • 1.为什么示例代码(1)中没有循环只有一个if函数算法复杂度也是O(n)?
  • 2.为什么示例代码(3)中的基本步骤执行的数量是n*(n-1)/2?
  • 首先回答第一个问题,我们观察一下示例代码:
  • decimal Factorial(int n) { if (n == 0) return 1; else return n * Factorial(n - 1); }
  • 我们可以看出来,这是一个计算阶乘的代码,那么计算阶乘要计算几次呢?(n次)所以这个代码的基本步骤执行的数量为 n,算法复杂度我们也可以轻易得出:是O(n)。
  • 第二个问题,示例代码如下:
  • long FindInversions(int[] array) { long inversions = 0; for (int i = 0; i < array.Length; i++) for (int j = i + 1; j < array.Length; j++) if (array[i] > array[j]) inversions++; return inversions; }
  • 这个代码的基本步骤执行的数量为n(n-1)/2,但我当时以为是nn/2。
  • 那么问题出在哪里呢?
  • 因为在代码if (array[i] > array[j]) 中,给出的是两个未知量的比较,所以我们要除以2。与另一个代码if (array[i] > max) { max = array[i]; }不同的是,这里我们需要考虑最坏情况,也就是这个代码要比较n次才能得到最大值。所以这个示例代码(2)的算法复杂度为O(n)。
  • 至于为什么是n*(n-1)那是因为每当for (int i = 0; i < array.Length; i++)循环一次的时候,for (int j = i + 1; j < array.Length; j++)要循环n-1次。
  • 所以最终这个代码的算法复杂度为O(n^2)。
  • 那么当我们理清思路的时候,我们也就能得出题目的答案。
  • 01的解题思路为:
  • 在while循环中,我们看到它给定的规模是n,算法基本执行的数量为n,所以算法复杂度为O(n)。
  • 02的解题思路为:
  • (1):
  • 给定规模n,则基本步骤的执行数量为n,所以算法复杂度为O(n)
  • (2):
  • 给定规模n,则基本步骤的执行数量为(n-1)*(n-1)/2,所以算法复杂度为O(n²)
  • (3):
  • 给定规模n,优化后算法复杂度为O(根号n)。
posted on 2017-11-21 22:04  20162319莫礼钟  阅读(233)  评论(0编辑  收藏