697. Degree of an Array

本文介绍了一种高效算法,用于查找具有与整个数组相同度数的最短连续子数组。通过使用两个哈希表,分别记录元素首次出现的位置和出现次数,实现了O(n)的时间复杂度。

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.

这道题整整花了快一个小时,试了好几种方法。先来分析题目,找到频率最大,距离最小的子数组的长度,根据上一道题的经验,只遍历一遍肯定是最优的解法,所以一开始我想的是用map寻找出频率最高的,再使用遍历数组找出元素的长度,但还是想用一种更为简便的方法去解,一般都是用空间去换时间。

这里声明了两个map,一个存储元素第一次出现的下标,第二个map存储出现的次数,通过len = min(i - map[nums[i]] + 1, len);来取出现频率相同的子数组中的最小长度,最后返回len

//
// Created by will on 2017/12/15.
//


/*
 * 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.
 */


#include <iostream>
#include <vector>
#include <unordered_map>

using namespace std;


class Solution {
public:
    int findShortestSubArray(vector<int>& nums) {
        unordered_map<int, int> map,count;

        int len = nums.size(), flag = 0;

        for (int i = 0; i < nums.size(); ++i) {
            if (map.count(nums[i]) == 0) map[nums[i]] = i;
            count[nums[i]]++;

            if(count[nums[i]] == flag){
                len = min(i - map[nums[i]] + 1, len);
            }

            if (count[nums[i]] > flag){
                len = i - map[nums[i]] + 1, len;
                flag = count[nums[i]];
            }

        }

        return len;




    }
};



int main(){
    vector<int> nums = {1,2,3,4,2};
    Solution s;
    int len = s.findShortestSubArray(nums);
    cout<<len;

    return 0;
}

  • Runtime: 59 ms
  • 时间复杂度:O(n);空间复杂度:O(1)
class CH_R(Directivity): """ Real cylindrical harmonics are a set of harmonic sine and cosine functions that are periodic with period 2pi. This class defines Directivities whose directional responses are cylindrical harmonics. Parameters ---------- order, degree : int Index to this cylindrical harmonics. ind : int Single-integer index, used if both order and degree are None. normalized : bool Specifies whether the directional response is normalized (i.e. unit mean square value). """ def __init__(self, order = None, degree = None, ind = None, normalized = True, **kwargs): super().__init__(**kwargs) self.set_normalized(normalized) if order is None and degree is None: order = (ind + 1) // 2 degree = 0 if order == 0 else (ind + 1) % 2 self.order = order self.degree = degree # Override def _get_params(self): return {'order' : self.order, 'degree' : self.degree, 'normalized' : self.normalized} # Override def _get_shortlabel(self): return 'CH' def dir_gain(self, azimuth, colatitude = None, degrees = False): """ Unoriented directional gain (which is a cylindrical harmonics). Parameters ---------- azimuth : array Angles (in radians) to return directional gains for. colatitude, frequency : None Unused. degrees : bool Whether angles are given in degrees. Returns ------- gain : array_like(azimuth) Directional gains in *azimuth*. """ if degrees: azimuth = np.radians(azimuth) if self.order == 0: return np.ones_like(azimuth) if self.degree == 0: return self.h_gain * np.cos(self.order * azimuth) if self.degree == 1: return self.h_gain * np.sin(self.order * azimuth) def get_wxy(self, oriented = True, azim = None, colat = None): """ Parameters *azim* and *colat* are unused. """ if self.order == 0: return np.array([1, 0, 0]) elif self.order == 1: if self.degree == 0: return np.array([0, 1, 0]) elif self.degree == 1: return np.array([0, 0, 1]) elif self.order > 1: if self.degree == 0 or self.degree == 1: return np.array([0, 0, 0]) def set_normalized(self, normalized): self.normalized = normalized if normalized: self.h_gain = np.sqrt(2) else: self.h_gain = 1 @staticmethod def rot_mats(max_order, rad): """ Compute a collection of rotation matrices for mixture-of-CH directivities. Parameters ---------- max_order : int Highest CH order to be rotated. rad : numeric Angle of rotation, in rads. Returns ------- mats : list[array] A list of *max_order* 2x2 matrices that rotate CH weights of orders 1, ..., max_order, respectively. """ if isinstance(rad, Orientation): rad = rad.get_azimuth() mats = [] for o in range(max_order): orad = (o + 1) * rad c = np.cos(orad) s = np.sin(orad) mats.append(np.array([[c, -s], [s, c]])) return mats @staticmethod def rotate(c, mats, axis = 0): """ Rotate one mixture-of-CH directional response to another. In typical usage *c* contains an odd number of channels (1 + 2 * max_order) and *mats* contain at least max_order 2x2 matrices. If less than max_order matrices are available the corresponding high order weights are not rotated. If *c* is even the imcomplete top order is not rotated. Parameters ---------- c : array Array encoding the original directional response as CH weights. By default the first dimension (axis 0) are the CH channels, i.e. c[0] contain weight(s) of the 0th order. This can be reconfigured via *axis*. mats : list[array2d] List of rotation matrices to be applied. See also rot_mats. axis : int Index of the axis that indices CH channels. Returns ------- c_rot : array Array encoding the rotated directional response as CH weights. """ c_rot = c + 0 c_rot = c_rot.swapaxes(0, axis) for o in range(min(len(mats), (len(c_rot) - 1) // 2)): # CH weights of order o + 1 c_o = c_rot[2 * o + 1 : 2 * o + 3] # Rotation matrices are left operators hence the transpose when applied on the right. # c_o[:] = c_o.T.dot(mats[o].T).T c_o[:] = np.tensordot(mats[o], c_o, axes=1) return c_rot.swapaxes(0, axis) @staticmethod def index_to_orderdegree(index): order = (index + 1) // 2 degree = 0 if index == 0 else (index - 1) // 2 return order, degree
最新发布
12-18
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值