美文网首页
数据结构和算法(二)-空间换取时间

数据结构和算法(二)-空间换取时间

作者: 烧伤的火柴 | 来源:发表于2020-07-06 14:22 被阅读0次

介绍

我们写算法的目的是尽可能的采用时间复杂度和空间复杂度都很低的算法。所以优化算法的时候我们都从时间和空间两个维度去考核。时间复杂度的调优可以使用递归,二分法,动态规划等等。空间的复杂度调优就要根据业务选择合适的数据结构,今天我们就看看如何选择数据机构?我们都听过使用空间复杂度替换时间复杂度的方案。

案例

查找数组中出现次数最多的那个元素和出现的次数。
比如 intArrayOf(3, 7, 5, 7, 8, 2, 7, 3, 8)
方法1:

fun findMaxTimes(): Pair<Int, Int> {
    val a = intArrayOf(3, 7, 5, 7, 8, 2, 7, 3, 8)
    var maxTimes = 0
    var valueOfMaxTimes = 0
    for (i in a.indices) {
        var tmpTimes = 0
        var tmpValue = a[i]
        for (m in a.indices) {
            val tmpValue2 = a[m]
            if (tmpValue == tmpValue2) {
                tmpTimes++
            }
            if (tmpTimes > maxTimes) {
                maxTimes = tmpTimes
                valueOfMaxTimes = tmpValue
            }
        }
    }

    return Pair(valueOfMaxTimes, maxTimes)
}

这种方法可读性高,逻辑就是使用两层循环,每次使用外部循环的元素和数组内的元素进行一一比较并且统计重复次数,找到最大重复次数的。这种算法的时间复杂度是O(n),空间复杂度没变。
方法2

fun findMaxTimes2(): Pair<Int, Int> {
    val a = intArrayOf(3, 7, 5, 7, 8, 2, 7, 3, 8)

    val groupMap: MutableMap<Int, Int> = mutableMapOf()
    a.forEach {
        val tmp = groupMap[it] ?: 0
        groupMap[it] = tmp + 1
    }

    val entry = groupMap.maxWith(Comparator { o1, o2 -> (o1!!.value.compareTo(o2!!.value)) })

    return Pair(entry?.key?:0,entry?.value?:0)
}

方法2中使用一个map统计所有元素的出现次数,然后遍历map找到最大次数的元素和次数。这种方法的时间复杂度是O(n),但是空间复杂度是O(n).
方法3


fun findMaxTimes3():Pair<Int,Int> {
    val a = intArrayOf(3, 7, 5, 7, 8, 2, 7, 3, 8)

    val b= IntArray(9)

    for (i in a) {
        val tmp = if(b[i]==0)1 else b[i]+1
        b[i]=tmp
    }

    var maxTimes=0
    var valueOfMaxTimes = 0
    for(p in b.withIndex()){
        if(maxTimes<p.value){
            maxTimes = p.value
            valueOfMaxTimes = p.index
        }
    }

    return valueOfMaxTimes to maxTimes
}

方法3有种取巧的方式了,因为数组的值都是10以内,而且长度也是小于10,所以定义一个等长的数组b,其中b的下标对应a数组的value,b的value存储的是重复次数。这种方式在内存方面会浪费一部分空间,比如极端情况下,a数组内都是8,那么b数组的index是8的位置有值,其他位置的空间都是浪费掉了。同样这种方法的时间和空间复杂度都是O(n)

总结

我们在算法优化的时候,值得优化的地方:
1.无效的计算和存储,删除无效的计算和存储,节约时间和空间复杂度。
2.采用合适的数据结构存储可以实现时间复杂度向空间复杂度的转移。
3.多层循环的时候,找到合适的跳转条件,跳出循环。

相关文章

  • 数据结构和算法(二)-空间换取时间

    介绍 我们写算法的目的是尽可能的采用时间复杂度和空间复杂度都很低的算法。所以优化算法的时候我们都从时间和空间两个维...

  • 算法复杂度

    数据结构: 数组、链表、栈、队列、二叉树、hash表、图。 空间复杂度和时间复杂度的算法 空间复杂度和时间复杂度 ...

  • 字节算法大神熬了三个通宵整理的数据结构与算法笔记(万字长文)

    数据结构与算法(一) 时间&空间复杂度 数据结构和算法的本质是解决“快”和“省”的问题:即如何让代码运行得更快、更...

  • Python语言进阶

    Python语言进阶 数据结构和算法 算法:解决问题的方法和步骤 评价算法的好坏:渐近时间复杂度和渐近空间复杂度。...

  • 【Python 100天从新手到大师】Python语言进阶

    Python语言进阶 数据结构和算法算法:解决问题的方法和步骤评价算法的好坏:渐近时间复杂度和渐近空间复杂度。渐近...

  • 熟记1

    dict是用空间来换取时间的一种方法。 通过key计算位置的算法称为哈希算法(Hash)。 set和dict的唯一...

  • Python-100天(二)-Python语言进阶

    数据结构和算法 算法:解决问题的方法和步骤 评价算法的好坏:渐近时间复杂度和渐近空间复杂度。 渐近时间复杂度的大O...

  • 如何学习数据结构和算法

    数据结构:表示如何存储数据的一种结构化方式。 算法:每种不同数据结构采用对应的算法才能达到最高效,时间复杂度和空间...

  • 数据结构与算法-复杂度分析

    时间、空间复杂度:衡量算法执行小路的指标,数据结构与算法离不开时间、空间复杂度分析,复杂度分析是算法的精髓。 为什...

  • 数据结构与算法之美2--复杂度分析(上)

    数据结构与算法 1 什么是复杂度分析? 1.数据结构和算法解决是“如何让计算机更快时间、更省空间的解决问题”。2....

网友评论

      本文标题:数据结构和算法(二)-空间换取时间

      本文链接:https://www.haomeiwen.com/subject/gcvwqktx.html