Given a non-empty array of non-negative integers nums, the degree of this array is defined as the maximum frequency of any one of its elements.

Your task is to find the smallest possible length of a (contiguous) subarray of nums, that has the same degree as nums.

Example 1:

Input: [1, 2, 2, 3, 1]
Output: 2
Explanation:
The input array has a degree of 2 because both elements 1 and 2 appear twice.
Of the subarrays that have the same degree:
[1, 2, 2, 3, 1], [1, 2, 2, 3], [2, 2, 3, 1], [1, 2, 2], [2, 2, 3], [2, 2]
The shortest length is 2. So return 2.

Example 2:

Input: [1,2,2,3,1,4,2]
Output: 6

Note:

  • nums.length will be between 1 and 50,000.
  • nums[i] will be an integer between 0 and 49,999.

这道题给了我们一个数组,定义数组的度为某个或某些数字出现最多的次数,要我们找最短的子数组使其和原数组拥有相同的度。那么我们肯定需要统计每个数字出现的次数,就要用哈希表来建立每个数字和其出现次数之间的映射。由于我们要求包含原度的最小长度的子数组,那么最好的情况就是子数组的首位数字都是统计度的数字,即出现最多的数字。那么我们肯定要知道该数字的第一次出现的位置和最后一次出现的位置,由于我们开始不知道哪些数字会出现最多次,所以我们统计所有数字的首尾出现位置,那么我们再用一个哈希表,建立每个数字和其首尾出现的位置。我们用变量degree来表示数组的度。好,现在我们遍历原数组,累加当前数字出现的次数,当某个数字是第一次出现,那么我们用当前位置的来更新该数字出现的首尾位置,否则只更新尾位置。每遍历一个数,我们都更新一下degree。当遍历完成后,我们已经有了数组的度,还有每个数字首尾出现的位置,下面就来找出现次数为degree的数组,然后计算其首尾位置差加1就是candidate数组的长度,由于出现次数为degree的数字不一定只有一个,我们遍历所有的,找出其中最小的即可,参见代码如下:

解法一:

class Solution {
public:
int findShortestSubArray(vector<int>& nums) {
int n = nums.size(), res = INT_MAX, degree = ;
unordered_map<int, int> m;
unordered_map<int, pair<int, int>> pos;
for (int i = ; i < nums.size(); ++i) {
if (++m[nums[i]] == ) {
pos[nums[i]] = {i, i};
} else {
pos[nums[i]].second = i;
}
degree = max(degree, m[nums[i]]);
}
for (auto a : m) {
if (degree == a.second) {
res = min(res, pos[a.first].second - pos[a.first].first + );
}
}
return res;
}
};

下面这种方法只用了一次遍历,思路跟上面的解法很相似,还是要建立数字出现次数的哈希表,还有就是建立每个数字和其第一次出现位置之间的映射,那么我们当前遍历的位置其实可以看作是尾位置,还是可以计算子数组的长度的。我们遍历数组,累加当前数字出现的次数,如果某个数字是第一次出现,建立该数字和当前位置的映射,如果当前数字的出现次数等于degree时,当前位置为尾位置,首位置在startIdx中取的,二者做差加1来更新结果res;如果当前数字的出现次数大于degree,说明之前的结果代表的数字不是出现最多的,直接将结果res更新为当前数字的首尾差加1的长度,然后degree也更新为当前数字出现的次数。参见代码如下:

解法二:

class Solution {
public:
int findShortestSubArray(vector<int>& nums) {
int n = nums.size(), res = INT_MAX, degree = ;
unordered_map<int, int> m, startIdx;
for (int i = ; i < n; ++i) {
++m[nums[i]];
if (!startIdx.count(nums[i])) startIdx[nums[i]] = i;
if (m[nums[i]] == degree) {
res = min(res, i - startIdx[nums[i]] + );
} else if (m[nums[i]] > degree) {
res = i - startIdx[nums[i]] + ;
degree = m[nums[i]];
}
}
return res;
}
};

类似题目:

Maximum Subarray

参考资料:

https://discuss.leetcode.com/topic/107097/java-o-n-time-o-n-space

https://discuss.leetcode.com/topic/107216/concise-c-solution-using-hash-map-o-n-time

http://www.cnblogs.com/grandyang/p/5265628.html

[LeetCode] Degree of an Array 数组的度的更多相关文章

  1. [LeetCode] 697. Degree of an Array 数组的度

    Given a non-empty array of non-negative integers nums, the degree of this array is defined as the ma ...

  2. Leetcode697.Degree of an Array数组的度

    给定一个非空且只包含非负数的整数数组 nums, 数组的度的定义是指数组里任一元素出现频数的最大值. 你的任务是找到与 nums 拥有相同大小的度的最短连续子数组,返回其长度. 示例 1: 输入: [ ...

  3. LeetCode Degree of an Array

    原题链接在这里:https://leetcode.com/problems/degree-of-an-array/description/ 题目: Given a non-empty array of ...

  4. [LeetCode] Longest Mountain in Array 数组中最长的山

    Let's call any (contiguous) subarray B (of A) a mountain if the following properties hold: B.length ...

  5. [LeetCode] 384. Shuffle an Array 数组洗牌

    Shuffle a set of numbers without duplicates. Example: // Init an array with set 1, 2, and 3. int[] n ...

  6. LeetCode 697. Degree of an Array (数组的度)

    Given a non-empty array of non-negative integers nums, the degree of this array is defined as the ma ...

  7. [Swift]LeetCode697. 数组的度 | Degree of an Array

    Given a non-empty array of non-negative integers nums, the degreeof this array is defined as the max ...

  8. C#LeetCode刷题之#697-数组的度( Degree of an Array)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3738 访问. 给定一个非空且只包含非负数的整数数组 nums, ...

  9. 【LeetCode】697. Degree of an Array 解题报告

    [LeetCode]697. Degree of an Array 解题报告 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/problems/degree- ...

随机推荐

  1. JS获得一个对象的所有属性和方法

    function displayProp(obj){ var names=""; for(var name in obj){ names+=name+": "+ ...

  2. 用java理解程序逻辑小结

    1.Java常见的注释有哪些,语法是怎样的? 1)单行注释用//表示,编译器看到//会忽略该行//后的所文本 2)多行注释/* */表示,编译器看到/*时会搜索接下来的*/,忽略掉/* */之间的文本 ...

  3. C语言中的atan和atan2

    本文内容为转载,是在阅读 RTKLIB源码时意识到的这个问题,原文地址为:https://www.cnblogs.com/dutlei/archive/2013/01/14/2860332.html ...

  4. alpha-咸鱼冲刺day4-紫仪

    总汇链接 一,合照 emmmmm.自然还是没有的. 二,项目燃尽图 三,项目进展 QAQ具体工作量没啥进展.但是前后端终于可以数据交互了!.. 四,问题困难   日常啥都不会,百度真心玩一年.   还 ...

  5. 利用PCA降维

    参考:<机器学习实战>- Machine Learning in Action 一. 基本思想  PCA(Principal Component Analysis),主成分分析.是目前应用 ...

  6. Linux系统安装gcc/g++详细过程

    下载: http://ftp.gnu.org/gnu/gcc/gcc-4.5.1/gcc-4.5.1.tar.bz2 浏览: http://ftp.gnu.org/gnu/gcc/gcc-4.5.1/ ...

  7. 在thinkphp框架中使用后台传值过来的数组,在hightcart中使用数组

    js的数组是和php里面数组是不一样的,所以模板文件需要先接受,然后利用Js代码转化之后再使用,接受后台的数组有几种办法 1.后台传过来的json数组,利用Js是可以接受的,然后将json数据利用js ...

  8. LeetCode & Q414-Third Maximum Number-Easy

    Array Math Description: Given a non-empty array of integers, return the third maximum number in this ...

  9. 源码解析flask的路由系统

    源码解析flask的路由系统 当我们新建一个flask项目时,pycharm通常已经为项目定义了一个基本路由 @app.route('/') def hello_world(): return 'He ...

  10. Spring Framework 的 Assert断言

    知识共享才能传播,博采众家之长,才能推陈出新!-- 参考 https://www.cnblogs.com/hwaggLee/p/4778101.html 一.什么是 Assert(断言)? Web 应 ...