Algorithm

本周的算法题为 128. 最长连续序列

给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。

请你设计并实现时间复杂度为 O(n) 的算法解决此问题。

示例 1

输入nums = [100,4,200,1,3,2]
输出4
解释最长数字连续序列是 [1, 2, 3, 4]它的长度为 4

实现代码如下:


var longestConsecutive = function (nums) {

    // 如果数组为空,则值为0,否则最小为1
    let sequenceMaxValue = nums.length == 0 ? 0 : 1
    
    let category = {}
    // 去重,使用对象key唯一性的特性实现数组去重。
    nums.forEach(item => {
        if (category[item]) {
            category[item].push(item)
        } else {
            category[item] = [item]
        }
    })

    let result = []
    // 获取最终的去重后的数组
    for (const key in category) {
        if (Object.hasOwnProperty.call(category, key)) {
            result.push(Number(key))

        }
    }
    // 将数组排序,从小到大排序
    result.sort((x, y) => {
        return x - y
    })

    
    // 设置顺序起点为数组下标为0的位置
    let latestStartIndex = 0
    // 设置顺序起点值,下标为0的值
    let latestStartValue = result[0]
    // 用来记录每个顺序,以起点为key,总共有多少次。
    let sequenceCountObject = {}

    result.forEach((item, index) => {
        // 因为设置了latestStartValue = result[0],默认会走else逻辑,sequenceCountObject[0]会多一次。
        if (index > 0) {
            // 实现的逻辑是,比如数组为[1,2,3,4,5,8,9,10],当后一个数,减去它的下标等于当前值latestStartValue(4-3=1),意味着还是处于顺序中,如果不是,比如到8了,那就开始新的顺序起点。
            // 其中,因为第一个起点数,不是每次都是下标0开始的,所以不能只是item - latestStartIndex,而是item - (index - latestStartIndex)拿到差值。
            if (item - (index - latestStartIndex) !== latestStartValue) {
                latestStartIndex = index
                latestStartValue = result[index]
            } else {
                
                // 如果当前值减去下标差值一直等于顺序起点值,意味着还处于顺序中,就加到对象这个以每个起点下标为key的值上,+1。
                if (sequenceCountObject[latestStartIndex]) {
                    sequenceCountObject[latestStartIndex] = sequenceCountObject[latestStartIndex] + 1
                } else {
                    //当对象中还没有存在这个起点下标的key时,默认从1开始,因为当latestStartIndex开始新的起点的时候,是走上面的if逻辑的,意味着这里要把起点的次数算上,所以是1+1,第一个1是起点,第二个1是记录次数
                    sequenceCountObject[latestStartIndex] = 1 + 1
                }

            }
        }
    })
    
    // 获取多个顺序长度的最大值,如果比当前值大,则赋值最新。
    for (const key in sequenceCountObject) {
        if (Object.hasOwnProperty.call(sequenceCountObject, key)) {
            const value = sequenceCountObject[key]
            if (value > sequenceMaxValue) {
                sequenceMaxValue = value
            }

        }
    }
    
    return sequenceMaxValue

解题思路:

首先将整个数组去重,然后从小到大排序,然后通过后一个数减去前一个数,其值是否为1来实现,主要思路是这个,但实现过程中,也是在不断地摸索,整体比前面两道题难很多,具体步骤如下:

  1. 如果数组为空,则最长连续序列值sequenceMaxValue为0,否则sequenceMaxValue最小为1。
  2. 去重,使用对象key唯一性的特性实现数组去重。
  3. 获取最终的去重后的数组。
  4. 将数组排序,从小到大排序。
  5. 将数组遍历,创建一个对象,用每个顺序起点作为key,判断数组中的元素是否在这个顺序中,如果是,其值+1,如果不是,开始新的顺序,使用新的顺序起点为key,以此类推。
  6. 然后将对象中,value最大的,就是当前数组中,最长连续序列值。

Review

The More You Do, The Easier It Gets | by Kevin Nokia Writing | Medium

作者主要是说之前一直喜欢玩电子游戏,花了很多时间在这上面,但是那都是短暂的快乐。所以他想要改变,想做一些值得的东西,那怎么能够改变呢?从习惯入手,在最初的14天或21天会很困难,但是在那之后,你的身体和心灵会帮助你养成你想要养成的新习惯,只需要21天,就会变得不一样,反复做你所做的事情,你做的越多,就越容易。最后,引用了一句宫本武藏的话:

”一开始可能看起来很困难,但一开始一切都很困难。“

image-20231108215109788

Tip

macflutter 怎么切换指定版本?在 flutter sdk目录下,运行命令 git checkout <指定版本>即可,比如 git checkout 3.3.10,然后使用命令 flutter version 查看当前版本,如下所示:截屏2023-11-07 17.42.03

Share

  1. 学习减肥知识可以在薄荷健康APP上面,有很多教程,可以都看看。

    image-20231103221345776
  2. 学习时间管理可以在滴答清单APP上面新手指南-最佳实践,上面有很多文章都很不错。

    image-20231103221454846