(1)算法复杂度分析之时间复杂度

381 阅读1分钟

算法复杂度分析

算法复杂度反映了算法执行时间和空间资源占用随问题规模增长的变化趋势。使用大O记号表示法可以指导算法设计和优化。

常见时间复杂度分析

O(1) 常数时间复杂度

O(1)表示执行时间是一个常数,和问题规模n无关。

案例:查找数组定位置元素

def get_element(arr, i):
  return arr[i] 

分析:get_element函数时间复杂度是O(1),无论数组大小,查找时间都是常数。

O(logn) 对数时间复杂度

O(logn)表示执行时间随问题规模n的对数增长。

案例:二分查找算法

def binary_search(arr, x):
  left, right = 0, len(arr)-1 
  while left <= right:
    mid = (left + right) // 2
    if x == arr[mid]:
      return mid 
    elif x < arr[mid]:
      right = mid - 1
    else:
      left = mid + 1
  return -1

分析:二分查找算法时间复杂度为O(logn),每次查找范围缩小一半,递归层数为问题规模n的对数。

O(n) 线性时间复杂度

O(n)表示执行时间随问题规模n线性增长。

案例:线性查找算法

def linear_search(arr, x):
  for i in range(len(arr)):
    if arr[i] == x:
      return i
  return -1

分析:线性查找需遍历数组一次,时间复杂度为O(n),随n线性增长。

O(nlogn) 对数线性时间复杂度

O(nlogn)表示执行时间随问题规模n对数线性增长。

案例:合并排序算法

def merge_sort(arr):
  # recursively divide array
  # merge divided arrays, O(n) per merge  
  
  return sorted_arr 

分析:合并排序递归划分和合并的时间复杂度为O(n),递归层数为O(logn),所以总时间为O(nlogn)。

O(n^2) 平方时间复杂度

O(n^2)表示执行时间随问题规模n平方增长。

案例:简单排序算法

def bubble_sort(arr):
  n = len(arr)
  
  for i in range(n):
    for j in range(0, n-i-1):
      if arr[j] > arr[j+1]:
        swap(arr[j], arr[j+1])
        
  return arr

分析: bubble_sort两层循环时间复杂度为O(n^2),随n平方增长。

O(2^n) 指数时间复杂度

O(2^n)表示执行时间随问题规模n指数增长。

案例:求解背包问题的递归算法

def knapsack(weights, values, n, maxWeight):
  if n == 0 or maxWeight == 0:
    return 0
  
  if weights[n-1] > maxWeight:
    return knapsack(weights, values, n-1, maxWeight)
  else:  
    return max(
      values[n-1] + knapsack(weights, values, n-1, maxWeight-weights[n-1]),
      knapsack(weights, values, n-1, maxWeight)
    )

分析:递归树分支数呈指数增长,时间复杂度为O(2^n)。

关注算法的时间复杂度,根据问题选择最优方案,可以提高程序效率。