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

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

问题

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

你的任务是找到与 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.

输入: [1,2,2,3,1,4,2]

输出: 6

注意:

nums.length 在1到50,000区间范围内。
nums[i] 是一个在0到49,999范围内的整数。

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.

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.

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.

示例

public class Statistics {
    //统计频次
    public int Count { get; set; }
    //开始索引
    public int StartIndex { get; set; }
    //结束索引
    public int EndIndex { get; set; }
}

public class Program {

    public static void Main(string[] args) {
        int[] nums = null;

        nums = new int[] { 1, 2, 2, 3, 1 };
        var res = FindShortestSubArray(nums);
        Console.WriteLine(res);

        Console.ReadKey();
    }

    private static int FindShortestSubArray(int[] nums) {
        //哈希存放统计数据
        var dic = new Dictionary<int, Statistics>();
        for(int i = 0; i < nums.Length; i++) {
            //如果有键,频次+1,记录结束索引
            if(dic.ContainsKey(nums[i])) {
                dic[nums[i]].Count++;
                dic[nums[i]].EndIndex = i;
            } else {
                //如果没有键,赋初始值
                dic.Add(nums[i], new Statistics {
                    Count = 1,
                    StartIndex = i,
                    EndIndex = i
                });
            }
        }
        //降序排列
        var order = dic.OrderByDescending(s => s.Value.Count).ToList();
        //记录数组的度
        var maxCount = order[0].Value.Count;
        //记录最小长度
        var minLength = int.MaxValue;
        //先筛选出所有与数组的度相同的统计结果 
        order.Where(s => s.Value.Count == maxCount)
             //转换成List  
             .ToList()
             //遍历所有List中的数据找出最小Length
             .ForEach(s => minLength = Math.Min(
                          minLength,
                          s.Value.EndIndex - s.Value.StartIndex + 1
                      ));
        //返回最小Length
        return minLength;
    }

}

以上给出1种算法实现,以下是这个案例的输出结果:

2

分析:

以上解法在最坏的情况下,var order = dic.OrderByDescending(s => s.Value.Count).ToList() 执行所消耗的时间最多,因为原数组可能没有重复的元素。若OrderByDescending基于比较的先进算法,那么以上解法的时间复杂度为: O(nlogn) ;若基于空间换时间的基数、计数或桶排序,那么以上解法的时间复杂度为: O(n) 。

本文由 .Net中文网 原创发布,欢迎大家踊跃转载。

转载请注明本文地址:https://www.byteflying.com/archives/3738

发表评论

登录后才能评论