LeetCode697- 数组的度 | 算法练习系列

78 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第18天,点击查看活动详情

前言

做事要有度,今天来一道数组相关的题目,本来看简单题目以为很简单,但做着做着就有点懵逼了,废话不多说,直接上题目。

题目描述

给定一个非空且只包含非负数的整数数组 nums,数组的 度 的定义是指数组里任一元素出现频数的最大值。

你的任务是在 nums 中找到与 nums 拥有相同大小的度的最短连续子数组,返回其长度。

示例 1:

输入:nums = [1,2,2,3,1] 输出:2 解释: 输入数组的度是 2 ,因为元素 1 和 2 的出现频数最大,均为 2 。 连续子数组里面拥有相同度的有如下所示: [1, 2, 2, 3, 1], [1, 2, 2, 3], [2, 2, 3, 1], [1, 2, 2], [2, 2, 3], [2, 2] 最短连续子数组 [2, 2] 的长度为 2 ,所以返回 2 。 示例 2:

输入:nums = [1,2,2,3,1,4,2] 输出:6 解释: 数组的度是 3 ,因为元素 2 重复出现 3 次。 所以 [2,2,3,1,4,2] 是最短子数组,因此返回 6 。

解题思路

这一题是虽然是简单难度的题目,但其中需要注意的点还是挺多的,而且我感觉题目有混淆视听的嫌疑,那就是题目中提到的连续子数组,我刚看到题目的时候想过把所有的子数组都列出来,但其实并不然,只要找到最长的满足条件的子数组就可以了。

  • 首先要找出数组中出现频数最多的项,这里要特别注意,这个项可能不是一个(很重要)
  • 用map来记录数组中各项出现的频数
  • 利用for...of...找到map中最大的value,也就是度
  • 接着再循环map,当map项的值等于度时就循环数组,如果当前项登录度对应的值时就存入数组;这里分两种情况,第一种情况是当结果数组,也就是resultArr为空并且还没遇到度对应的key时;一种是当resultArr已经有项并且遇到项不等于key时,这时也要push进resultArr
  • 没当遇到项等于key时,除了要push进数组外,degree也要减减
  • 这里用maxLength来记录最短连续子数组,因此要分两种情况,第一种是整个数组中出现频数最多的值是唯一的情况,那这时候maxLength = resultArr.length即可;另一种就是数组中频数最多的值不值一个,那就要取resultArr.length最短的那个了

代码如下:

/**
 * @param {number[]} nums
 * @return {number}
 */

var getMax = function (map) {
    let max = 0
    for (let [key, value] of map) {
        if (value > max) {
            max = value
        }
    }
    return max
}
var findShortestSubArray = function (nums) {
    var maxLength = 0
    var map = new Map()
    for (let i = 0; i < nums.length; i++) {
        if (!map.get(nums[i])) {
            map.set(nums[i], 1)
        } else {
            map.set(nums[i], map.get(nums[i]) + 1)
        }
    }

    for (let [key, value] of map) {
        let degree = getMax(map)
        if (value === degree) {
            let resultArr = []
            for (let j = 0; j < nums.length && degree > 0; j++) {
                if (resultArr.length === 0 && nums[j] === key) {
                    resultArr.push(nums[j])
                    degree--
                } else if (resultArr.length > 0) {
                    resultArr.push(nums[j])
                    if (nums[j] === key) {
                        degree--
                    }
                }
            }
            if (!maxLength) {
                maxLength = resultArr.length
            }
            if (maxLength > resultArr.length) {
                maxLength = resultArr.length
            }
        }
    }

    return maxLength
};

运行结果如下图:

image.png