274.H指数
题目理解
给定研究者的论文引用数数组。H指数是指N篇论文中有H篇被引用了至少H次,其余N-H篇不超过H次。说白了就是统计数组中符合条件的那个最大值。举个例子,引用数组为[3,0,6,1,5],引用数>=0的有5篇,符合(0,0)条件;引用数>=1的有4篇。符合(1,1)条件;引用数>=2的有3篇,符合(2,2);引用数>=3的有3篇,符号(3,3);引用数>=4的有两篇,不符合(4,4)。
解题思路
①开始时考虑对数组进行从大到小排序,则排序后数组下标+1就相当于>=当前引用数的篇数。要寻找的是在(h,h)内的最大值。如果下标+1>数组当前元素则说明满足(h,h),因此问题改为了寻找排序后第一个下标+1>数组当前元素的数。涉及到排序,所以时间复杂度为O(NlogN).
②另一种思路是计数。显然H指数必小于等于文章数即数组长度n,因此将所有引用次数大于n的都变为n,不会影响结果。将每个引用次数出现的次数存下来,则比当前数组下标(即引用数)大的文章数,为当前数组元素之后的元素之和。因此循环时可以倒着来,进行累加。时间复杂度为O(n)。
代码
①
class Solution {
public:
int hIndex(vector<int>& citations) {
int n=citations.size();
sort(citations.begin(),citations.end());//从小到大排序,所以循环得倒着来
int i=0;
for(;i<n;i++)
{
if(citations[n-1-i]<(i+1))
break;
}
return i;
}
};
②
class Solution {
public:
int hIndex(vector<int>& citations) {
int n=citations.size();
vector<int> number(n+1,0);
for(auto i:citations){
++number[min(i,n)];
}
int k=n;
for(int s=number[n];s<k;s+=number[k])
k--;
return k;
}
};
453最小操作数使数组元素相等
题目理解(不简单的简单题)
数组n个元素,每次操作给n-1个元素+1,求最小操作次数使数组元素相等。
如[1,2,3],只需要3次操作(注意每次操作会增加两个元素的值):
[1,2,3] => [2,3,3] => [3,4,3] => [4,4,4]
思路
①显然要使数组元素相等,每次+1的n-1个元素一定是数组中最小的n-1个元素。如果把数组排序,最小值一定是从始至终都在进行操作的数,且不用每次都加1,当前最小值一定会先加够最大值与最小值之间的差值,以[1,2,3]为例,最大为nums[n-1]=3,最小nums[0]=1,则至少+2,变为[3,4,3],当前最大值变为nums[n-2]=4,最小值仍然为nums[0],当前除最大值外的其他元素再加4-3=1,变为[4,4],操作次数为第一次的+2,第二次的+1,即为3.
②动态规划
仍然排序,一步一步考虑,每次都让前面的i-1的元素相等,则第i个元素,只需i-1前的元素再加上nums[i]-nums[i-1]。但数组毕竟是个整体,再给第一个第二个元素进行操作时,后面的元素也会同时进行操作。因此需要一个变量统计总的操作次数。
③数学方法
对n-1个最小元素+1,其实等效于对最大的元素-1,因此只需要找到让所有元素都减小到最小值的次数即为解。
代码
①
class Solution {
public:
int minMoves(vector<int>& nums) {
int n=nums.size();
sort(nums.begin(),nums.end())