作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


题目地址:https://leetcode.com/problems/degree-of-an-array/description/

题目描述

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:

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

题目大意

数组的度是出现次数最多的数字的出现次数。求一个最短子数组的长度,其度等于数组的度。

解题方法

求出最短相同子数组度的长度

题目大意:

给定非空非负整数数组,数组的度是指元素的最大出现次数。

寻找最大连续区间,使得区间的度与原数组的度相同。

想法很粗暴,直接求出整个数组的degree,然后找出所有的度等于该degree的数,找出最小度的数。

import collections
class Solution(object):
def findShortestSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if len(nums) == len(set(nums)):
return 1
counter = collections.Counter(nums)
degree_num = counter.most_common(1)[0]
most_numbers = [num for num in counter if counter[num] == degree_num[1]]
scale = 100000000
for most_number in most_numbers:
appear = [i for i,num in enumerate(nums) if num == most_number]
appear_scale = max(appear) - min(appear) + 1
if appear_scale < scale:
scale = appear_scale
return scale

上面使用了Counter,下面的直接数,速度有一点提高。

import collections
class Solution(object):
def findShortestSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
nums_set = set(nums)
if len(nums) == len(nums_set):
return 1
degree = max([nums.count(num) for num in nums_set])
most_numbers = [num for num in nums_set if nums.count(num) == degree]
scale = 100000000
for most_number in most_numbers:
appear = [i for i,num in enumerate(nums) if num == most_number]
appear_scale = max(appear) - min(appear) + 1
if appear_scale < scale:
scale = appear_scale
return scale

上面的不够快是因为重复计算了多次的nums.count(num),避免重复计算可以使用字典进行保存。这个方法超出了96.7%的提交。

import collections
class Solution(object):
def findShortestSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
nums_set = set(nums)
if len(nums) == len(nums_set):
return 1
num_dict = {num:nums.count(num) for num in nums_set}
degree = max(num_dict.values())
most_numbers = [num for num in nums_set if num_dict[num] == degree]
scale = 100000000
for most_number in most_numbers:
appear = [i for i,num in enumerate(nums) if num == most_number]
appear_scale = max(appear) - min(appear) + 1
if appear_scale < scale:
scale = appear_scale
return scale

还能更快吗?可以。把能压缩的列表表达式拆开,这样迭代一次就可以了。最后用了个提前终止,如果scale==degree说明这段子列表里没有其他元素了,一定是最短的。

这个方法超过了99.91%的提交。

import collections
class Solution(object):
def findShortestSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
nums_set = set(nums)
if len(nums) == len(nums_set):
return 1
num_dict = {}
degree = -1
for num in nums_set:
_count = nums.count(num)
num_dict[num] = _count
if _count > degree:
degree = _count
most_numbers = [num for num in nums_set if num_dict[num] == degree]
scale = 100000000
for most_number in most_numbers:
_min = nums.index(most_number)
for i in xrange(len(nums)-1, -1, -1):
if nums[i] == most_number:
_max = i
break
appear_scale = _max - _min + 1
if appear_scale < scale:
scale = appear_scale
if scale == degree:
break
return scale

使用堆求最大次数和最小长度

二刷的时候,想到其实同时优化两个指标:最大次数和最小长度。所以,直接遍历所有的数字,同时统计它的次数,起始位置和结束位置,然后用一个堆,进行最大次数和最小长度的选择,对应的长度就是最小长度。

class Solution:
def findShortestSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
count = collections.defaultdict(tuple)
for i, num in enumerate(nums):
if num not in count:
count[num] = (1, i, i)
else:
count[num] = (count[num][0] + 1, count[num][1], i)
heap = [(-times, end - start + 1) for times, start, end in count.values()]
heapq.heapify(heap)
return heapq.heappop(heap)[1]

保存最左边出现位置和最右边出现位置

使用两个字典,保存每个数字出现的最左边和最右边位置,这样的话,我们找到了出现次数等于数组的度的数字,然后看它的长度是不是最小的即可。

class Solution:
def findShortestSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
left, right = dict(), dict()
count = collections.defaultdict(int)
for i, num in enumerate(nums):
if num not in left:
left[num] = i
right[num] = i
count[num] += 1
degree = max(count.values())
res = float("inf")
for num, c in count.items():
if c == degree:
res = min(res, right[num] - left[num] + 1)
return res

日期

2018 年 1 月 23 日
2018 年 11 月 16 日 —— 又到周五了!

【LeetCode】697. Degree of an Array 解题报告(Python)的更多相关文章

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

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

  2. 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 ...

  3. LeetCode: Search in Rotated Sorted Array 解题报告

    Search in Rotated Sorted Array Suppose a sorted array is rotated at some pivot unknown to you before ...

  4. [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 ...

  5. leetcode 697. Degree of an Array

    题目: Given a non-empty array of non-negative integers nums, the degree of this array is defined as th ...

  6. 【LeetCode】26. Remove Duplicates from Sorted Array 解题报告(Python&C++&Java)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 双指针 日期 [LeetCode] https:// ...

  7. 【LeetCode】912. Sort an Array 解题报告(C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 库函数排序 桶排序 红黑树排序 归并排序 快速排序 ...

  8. 【LeetCode】941. Valid Mountain Array 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  9. 【LeetCode】88. Merge Sorted Array 解题报告(Java & Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 新建数组 日期 题目地址:https://leetc ...

随机推荐

  1. illumina SNP 芯片转基因型矩阵

    一.芯片数据 此次拿到的illumina芯片数据并不是原始的数据,已经经过GenomeStudio软件处理成了finalreport文件,格式如下: 之前没处理过芯片数据,对于这种编码模式(Forwa ...

  2. C++类成员初始化列表的构造顺序

    看下面代码, 输出结果是多少呢? class A{ public: A(int k) : j(k), i(j) { } void show() { cout << this->i & ...

  3. 06 windows安装Python+Pycharm+Scrapy环境

    windows安装Python+Pycharm+Scrapy环境 使用微信扫码关注微信公众号,并回复:"Python工具包",免费获取下载链接! 一.卸载python环境 卸载以下 ...

  4. A Child's History of England.29

    You have not forgotten the New Forest which the Conqueror made, and which the miserable people whose ...

  5. 零基础学习java------21---------动态代理,java8新特性(lambda, stream,DateApi)

    1. 动态代理 在一个方法前后加内容,最简单直观的方法就是直接在代码上加内容(如数据库中的事务),但这样写不够灵活,并且代码可维护性差,所以就需要引入动态代理 1.1 静态代理实现 在讲动态代理之前, ...

  6. C语言把数字转换为字符串的函数

    博主原文 C语言itoa()函数和atoi()函数详解(整数转字符C实现) C语言提供了几个标准库函数,可以将任意类型(整型.长整型.浮点型等)的数字转换为字符串. 1.int/float to st ...

  7. vue项目windows环境初始化

    下载nodejs zip包并加载到环境变量 nodejs的版本最好使用12版,而不是最新版 npm install webpack -gnpm install -g yarnyarn config s ...

  8. 关于java构造器

    关于java的构造器.首先构造器并不会创建java对象,构造器知识负责执行初始化,在构造器执行之前,Java对象所需要的内存空间是由new关键字申请出来的.大部分时候,程序使用new关键字为一个Jav ...

  9. Springboot,SSM及SSH的概念、优点、区别及缺点

    Springboot的概念: 是提供的全新框架,使用来简化Spring的初始搭建和开发过程,使用了特定的方式来进行配置,让开发人员不在需要定义样板化的配置.此框架不需要配置xml,依赖于像MAVEN这 ...

  10. ICCV2021 | 用于视觉跟踪的学习时空型transformer

    ​  前言  本文介绍了一个端到端的用于视觉跟踪的transformer模型,它能够捕获视频序列中空间和时间信息的全局特征依赖关系.在五个具有挑战性的短期和长期基准上实现了SOTA性能,具有实时性,比 ...