常见算法复杂度

时间复杂度

常见的算法时间复杂度:O(1)<O(logN)<O(N)<O(NlogN)<O(N2)<O(2N)<O(N!)

public class TimeComplexity {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        algorithm01(10000);
        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }

    // 常数O(1):运行次数与n大小呈常数关系,即不随输入数据大小n的变化而变化
    public static int algorithm01(int n) {
        int a = 1, b = 2;
        int x = a * b + n;
        return x;
    }
    // 无论a取多大,都与输入数据大小n无关,因此时间复杂度仍为O(1)
    public static int algorithm11(int n) {
        int count = 0;
        int a = 10000;
        for (int i = 0; i < a; i++) {
            count++;
        }
        return count;
    }

    // 线性O(N):循环运行次数与n大小呈线性关系
    public static int algorithm02(int n) {
        int count = 0;
        for (int i = 0; i < n; i++) {
            count++;
        }
        return count;
    }
    // 虽然是两层循环,但第二层与n大小无关,因此整体仍与n呈线性关系
    public static int algorithm12(int n) {
        int count = 0;
        int a = 10000;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < a; j++) {
                count++;
            }
        }
        return count;
    }

    // 平方O(N^2):两层循环相互独立,都与n呈线性关系,因此总体与n呈平方关系
    public static int algorithm03(int n) {
        int count = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                count++;
            }
        }
        return count;
    }

    // 指数O(2^N):指数阶常出现于递归
    public static int algorithm04(int n) {
        if (n <= 0) {
            return 1;
        }
        int count1 = algorithm04(n - 1);
        int count2 = algorithm04(n - 1);
        return count1 + count2;
    }

    // 阶乘O(N!):阶乘常使用递归实现
    public static int algorithm05(int n) {
        if (n <= 0) {
            return 1;
        }
        int count = 0;
        for (int i = 0; i < n; i++) {
            count += algorithm05(n - 1);
        }
        return count;
    }

    // 对数O(logN):对数阶与指数阶相反,指数阶为"每轮分裂出两倍的情况" ,而对数阶是"每轮排除一半的情况"。
    // 对数阶常出现于二分法、分治等算法中,体现着"一分为二"或"一分为多"的算法思想
    public static int algorithm06(int n) {
        int count = 0;
        float i = n;
        while (i > 1) {
            i /= 2;
            count++;
        }
        return count;
    }

    // 线性对数(NlogN):两层循环相互独立,第一层和第二层时间复杂度分别为O(logN)和O(N)
    // 线性对数阶常出现于快速排序、归并排序、堆排序等排序算法中
    public static int algorithm07(int n) {
        int count = 0;
        float i = n;
        while (i > 1) {
            i = i / 2;
            for (int j = 0; j < n; j++) {
                count++;
            }
        }
        return count;
    }
}
空间复杂度

常见的算法空间复杂度:常见的算法空间复杂度:O(1)<O(logN)<O(N)<O(N2)<O(2N)

public class SpaceComplexity {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        algorithm01(10);
        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }

    // 普通常量、变量、对象、元素数量与输入数据大小n无关的集合,皆使用常数大小的空间
    public static void algorithm01(int n) {
        int NUM = 0;
        int[] nums = new int[10];
        Node node = new Node(0);
        Map<Integer, String> map = new HashMap<>();
        map.put(0, "0");
    }
    // test()调用了n次,但每轮调用后test()已返回,无累计栈帧空间使用,因此空间复杂度仍为O(1)
    public static void algorithm11(int n) {
        for (int i = 0; i < n; i++) {
            Node.test();
        }
    }

    // 元素数量与n呈线性关系的任意类型集合(常见于一维数组、链表、哈希表等),皆使用线性大小的空间
    public static void algorithm02(int n) {
        int[] num1 = new int[n];
        int[] num2 = new int[n / 2];

        ArrayList<Node> nodes = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            nodes.add(new Node(i));
        }

        HashMap<Integer, String> map = new HashMap<>();
        for (int i = 0; i < n; i++) {
            map.put(i, String.valueOf(i));
        }
    }
    // 递归调用期间,会同时存在n个未返回的algorithm12()函数,因此使用O(N)大小的栈帧空间
    public static int algorithm12(int n) {
        if (n <= 1) {
            return 1;
        }
        return algorithm12(n - 1) + 1;
    }

    // 平方O(N^2):元素数量与n呈平方关系的任意类型集合(常见于矩阵),皆使用平方大小的空间
    public static void algorithm03(int n) {
        int[][] arr = new int[n][n];

        List<List<Node>> lists = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            List<Node> nodes = new ArrayList<>();
            for (int j = 0; j < n; j++) {
                nodes.add(new Node(j));
            }
            lists.add(nodes);
        }
    }

    // 指数O(2^N):指数阶常见于二叉树、多叉树

    // 对数O(logN):对数阶常出现于分治算法的栈帧空间累计(快速排序)、数据类型转换(数字转字符串)等
}

class Node {
    int val;    // 变量
    Node next;  // 动态数组
    // 动态对象
    Node(int x) {
        val = x;
    }

    static void test(){}
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值