数据结构与算法学习笔记(一)复杂度

复杂度

时间复杂度

常见时间复杂度为:
常量阶O(1),对数阶O(logN),线性阶O(n),线性对数阶O(nlogN),平方阶O(n2)

非常用算法时间复杂度,非多项式量级:
指数阶O(2n),阶乘阶O(n!)

O(logN),O(nlogN),例:

i=1; while (i <= n) { i = i * 2; }

复杂度为O(log2N),记为O(logN)。

O(m+n),O(m*n),例:

int cal(int m, int n) {
  int sum_1 = 0;
  int i = 1;
  for (; i < m; ++i) {
    sum_1 = sum_1 + i;
  }
  int sum_2 = 0;
  int j = 1;
  for (; j < n; ++j) {
    sum_2 = sum_2 + j;
  }
  return sum_1 + sum_2;
}

因为m和n无法判定量级,不能以常数形式省略,所以复杂度为O(m+n)。

最好、最坏情况时间复杂度

指的是最理想、最糟糕情况下,执行这段代码的时间复杂度。

平均情况时间复杂度、期望时间复杂度

将每种情况下所需要的复杂度因数累加,除以可能发生的情况数量,即为平均时间复杂度

在计算平均时间复杂度时将每种情况的概率也加进去,即为加权平均时间复杂度期望时间复杂度

均摊时间复杂度

将复杂的操作均摊到其他操作内,是一种特殊的平均时间复杂度。

 // array表示一个长度为n的数组
 // 代码中的array.length就等于n
 int[] array = new int[n];
 int count = 0;
 void insert(int val) {
    if (count == array.length) {
       int sum = 0;
       for (int i = 0; i < array.length; ++i) {
          sum = sum + array[i];
       }
       array[0] = sum;
       count = 1;
    }
    array[count] = val;
    ++count;
 }

在这个程序中,当array满了之后在进行插入要将所有记录的sum值放到array[0]中,然后指向array头部重新插入。

在这个情况下,当数组占满之后进行一次O(n),随后每次插入都是O(1)直到再次占满。

均摊时间复杂度:(n+(n-1)*1)/n = O(1)

空间复杂度

O(1),O(n),O(n2),例:

void print(int n) {
  int i = 0;
  int[] a = new int[n];
  for (i; i <n; ++i) {
    a[i] = i * i;
  }
  for (i = n-1; i >= 0; --i) {
    print out a[i]
  }
}

仅申请了一个a的空间,空间复杂度为O(n)。

问题

// 全局变量,大小为10的数组array,长度len,下标i。
int array[] = new int[10]; 
int len = 10;
int i = 0;
// 往数组中添加一个元素
void add(int element) {
   if (i >= len) { // 数组空间不够了
     // 重新申请一个2倍大小的数组空间
     int new_array[] = new int[len*2];
     // 把原来array数组中的数据依次copy到new_array
     for (int j = 0; j < len; ++j) {
       new_array[j] = array[j];
     }
     // new_array复制给array,array现在大小就是2倍len了
     array = new_array;
     len = 2 * len;
   }
   // 将element放到下标为i的位置,下标i加一
   array[i] = element;
   ++i;
}

最好情况时间复杂度为O(1),最坏情况时间复杂度为O(n),均摊时间复杂度为O(1)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值