这道题目直接遍历找出最大最小值,统计好就好了。
代码如下:
class Solution {
public:
double average(vector<int>& salary) {
int maxnum,minnum;
maxnum = minnum = salary[0];
double sum = 0;
for(int i = 0;i<salary.size();i++)
{
sum += salary[i];
if(maxnum<salary[i])
maxnum = salary[i];
if(minnum>salary[i])
minnum = salary[i];
}
return (sum - maxnum - minnum)/(salary.size()-2);
}
};
这道题关键在于去重,比如25,因子:1,5,25。比如:1,因子只有1
我的想法是:
1.对于1经行特判
2.加入1,n这两个因子
3.从2开始,直到根号n。所有的不一样的因子加入进去
4.排序
5.输出
class Solution {
public:
int kthFactor(int n, int k) {
vector<int> p;
if(n==1)
{
if(k==1)
return 1;
else
return -1;
}
p.push_back(1);
p.push_back(n);
for(int i = 2;i<=sqrt(n);i++)
{
if(n%i==0)
{
p.push_back(i);
if(n/i!=i)
p.push_back(n/i);
}
}
sort(p.begin(),p.end());
if(k<=p.size())
return p[k-1];
return -1;
}
};
小编想法:
1.我们先进行特判,全为0,输出0,全为1,输出n-1。(必须减去一个)
2.我们统一看成0,1序列交替出现。
3.统计个数,压入数组。偶数代表0的序列个数,单数代表1的序列个数
4.从下标为:2开始判断是不是1。每次自加2。如果为1,查看是不是产生新的最大值
int flag = false;
for(int i = 0 ;i < nums.size();i++)
{
if(nums[i]!=0)
{
flag = true;
}
}
if(!flag)
return 0;
flag = false;
for(int i = 0 ;i < nums.size();i++)
{
if(nums[i]!=1)
{
flag = true;
}
}
if(!flag)
return nums.size()-1;
vector<int> tt;
int sum = 0;
int maxnum = 0;
for(int i = 0 ;i < nums.size();i++)
{
sum = 0;
for(;i < nums.size();i++)
{
if(nums[i]!=0)
{
break;
}
sum++;
}
tt.push_back(sum);
sum = 0;
for(;i < nums.size();i++)
{
if(nums[i]!=1)
{
break;
}
sum++;
}
maxnum = max(sum,maxnum);
tt.push_back(sum);
i--;//自加会导致如果少算一个0
}
for(int i = 2;i<tt.size();i+=2)
{
if(tt[i]==1&&i+1<tt.size())
{
maxnum = max(tt[i-1]+tt[i+1],maxnum);
}
}
return maxnum;
}
这道题我有两种思路,但是在写博客前没有去证明这是对的
方法一:
1.用并查集选出层次最多的树,毕竟在怎么排,都不可能小于这个值
2.然后选出层次次一点的树,加入在之前的树没有排满的学期,插进去
方法二:
1.回溯遍历出所有的情况,可以使用剪枝的方法,减少复杂度。
附上其他人的代码:
class Solution {
public:
int minNumberOfSemesters(int n, vector<vector<int>>& dependencies, int k) {
vector<int> pre(n); //如果pre[i]的二进制第j位是1,表示j到i有一条边
for(auto& e : dependencies){
e[0] -= 1; //序号变成[0,n)
e[1] -= 1;
pre[e[1]] |= 1 << e[0]; //根据定义,将pre[e[1]]的第e[0]位变成1
}
//如何用二进制表示集合:
//i表示一个课程集合,如果i的二进制第j位1,那么表示第j个课程属于这个集合
//i的取值范围是从二进制00...00到二进制11...11,也就是从0到(1<<n)-1
vector<int> dp(1 << n, n);
//dp[i]表示学完i表示的课程集合最少步数,初始化成n,因为学完所有课不可能超过n步
dp[0] = 0; //不学任何课程只需要0步
for(int i = 0; i < (1 << n); i += 1){//按某个顺序枚举i
int ex = 0; //用ex表示学完i的课程后现在可以学哪些课程,如果ex的二进制第j位1,那么表示可以先第j个课程
for(int j = 0; j < n; j += 1) if((i & pre[j]) == pre[j]) ex |= 1 << j;
//枚举所有课程,(i&pre[j])==pre[j]表示pre[j]是i的子集,如果i包含pre[j],那么就可以学习j
ex &= ~i;//从ex里去掉i,避免重复
for(int s = ex; s; s = (s - 1) & ex) //这样可以枚举ex的所有非空子集s,具体见搜索引擎
if(__builtin_popcount(s) <= k) //如果这个集合大小小于等于k
dp[i | s] = min(dp[i | s], dp[i] + 1);
//更新答案,由于i<(i|s),所以可以按i从小到大的顺序枚举
}
return dp.back();//最后一个值,也就是dp[(1<<n)-1]
}
};
作者:何逊
链接:https://leetcode-cn.com/circle/discuss/zPlu04/view/bivCj2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。