zoukankan      html  css  js  c++  java
  • 算法复杂度O(logn)详解

    一.O(logn)代码小证明

    我们先来看下面一段代码:

    int cnt = 1;
    
    while (cnt < n)
    {
        cnt *= 2;
        //时间复杂度为O(1)的程序步骤序列
    }
    

    由于cnt每次在乘以2之后都会更加逼近n,也就是说,在有x次后,cnt将会大于n从而跳出循环,所以(2 ^ x = n), 也就是(x = log_2n),所以这个循环的复杂度为O(logn)

    二.典型时间复杂度

    $c$ 常数
    $logN$ 对数级
    $log ^ 2N$ 对数平方根
    $N$ 线性级
    $NlogN$
    $N ^ 2$ 平方级
    $N ^ 3$ 立方级
    $2 ^ N$ 指数级
    

    由此我们可以得知,(logN)的算法效率是最高的

    三.常见的(logN)算法

    1.对分查找

    - (int)BinarySearch:(NSArray *)originArray element:(int)element
    {
        int low, mid, high;
        low = 0; high = (int)originArray.count - 1;
        while (low <= high) {
            mid = (low + high) / 2;
            if ([originArray[mid] intValue] < element) {
                low = mid + 1;
            } else if ([originArray[mid] intValue] > element) {
                high = mid -1;
            } else {
                return mid;
            }
        }
        
        return -1;
    }
    

    2. 欧几里得算法

    - (unsigned int)Gcd:(unsigned int)m n:(unsigned int)n
    {
        unsigned int Rem;
        while (n > 0) {
            Rem = m % n;
            m = n;
            n = Rem;
        }
        return m;
    }
    

    3.幂运算

    - (long)Pow:(long)x n:(unsigned int)n
    {
        if (n == 0) {
            return 1;
        }
        if (n == 1) {
            return x;
        }
        
        if ([self isEven:n]) {
            return [self Pow:x * x n:n / 2];
        } else {
            return [self Pow:x * x n:n / 2] * x;
        }
    }
    
    - (BOOL)isEven:(unsigned int)n
    {
        if (n % 2 == 0) {
            return YES;
        } else {
            return NO;
        }
    }
    

    四.$$库里的log函数

    在$$库里有log()函数和log2()函数

    log()函数的底数默认为自然对数的底数e

    log2()函数的底数很显然就是2咯qwq

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    
    using namespace std;
    //#define DEBUG(x) cerr << #x << "=" << x << endl
    
    int main()
    {
        cout << log(M_E) << endl;
        cout << log2(2) << endl;
        return 0;
    }
    

    然后我们就会得到

    1
    1
    

    的结果

    [库里有两个常量M_E和M_PI M_E代表的是自然对数的底数e M_PI代表的是圆周率π ## 最后,也是最基本的最重要的 当题目的数据范围达到了$10^{18}$的时候,很显然就要用O(logn)的算法或数据结构了]

  • 相关阅读:
    85. Maximal Rectangle
    120. Triangle
    72. Edit Distance
    39. Combination Sum
    44. Wildcard Matching
    138. Copy List with Random Pointer
    91. Decode Ways
    142. Linked List Cycle II
    异或的性质及应用
    64. Minimum Path Sum
  • 原文地址:https://www.cnblogs.com/linhaostudy/p/11659846.html
Copyright © 2011-2022 走看看