Skip to content

Latest commit

 

History

History
 
 

1838.Frequency-of-the-Most-Frequent-Element

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

1838.Frequency-of-the-Most-Frequent-Element

首先需要明确,我们操作后最终得到的最高频率元素一定是数组中既有的元素。为什么?假设你可以通过操作,得到一个最高频率的元素是x,且x在原数组中没有出现过;那么你必然可以通过更少的一些操作,使得原数组里恰好比x小的元素y,也构造出相同的频次。因此我们不妨将nums按从小到大排序。

那么这个最高频次的元素是什么呢?显然不一定是数组里既有的最高频次元素。我们必须逐个尝试一遍。假设我们通过不超过k次的操作,使nums[i]的频次最高,那么这些操作必然是作用在紧邻i前面的若干元素,使它们变成nums[i]。我们假设操作的范围是[j:i-1],需要的实际操作数就是count = sum{nums[i]-nums[k]}, k=j,j+1, ... i-1

接下来我们考虑如果最终最高频次的元素是nums[i+1],那么我们如何高效地转移?假设需要操作的数的范围起点不变,即[j:i],那么总操作数的增量就是count += (nums[i+1]-nums[i])*(i+1-j),也就是我们将nums[j:i-1]都变成nums[i]的基础上,再将这(i+1-j)个数都提升一个gap,变成nums[i+1]。此时如果count>k了,那么我们就要优先舍弃最前面的元素j,那么节省的操作数就是nums[i+1]-nums[j]。我们可能会舍弃若干个老元素并右移j,直至是的count<=k,那么此时我们就在题目的限制条件下,可以将nums[j:i]都变成了nums[i+1],即频次就是i+1-j+1.

所以本题的实质就是维护一个最大滑窗[j:i],使得滑窗内所有元素到nums[i]的距离之和小于等于k,具体实现时,用for循环控制i一步一步推进,再灵活调整j右移,使得总操作数count<=k。