暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Leetcode第232场周赛

fighting小王子 2021-03-18
459

这次周赛整体难度不是很大。


1790. 仅执行一次字符串交换能否使两个字符串相等



题目描述:

给你长度相等的两个字符串 s1 和 s2 。一次 字符串交换 操作的步骤如下:选出某个字符串中的两个下标(不必不同),并交换这两个下标所对应的字符。

如果对 其中一个字符串 执行 最多一次字符串交换 就可以使两个字符串相等,返回 true ;否则,返回 false 。

(看一个串是否是另一个串交换两个字符位置而来。)


样例:


输入:s1 = "bank", s2 = "kanb"
输出:true
解释:例如,交换 s2 中的第一个和最后一个字符可以得到 "bank"


数据约束:

1 <= s1.length, s2.length <= 100
s1.length == s2.length
s1 和 s2 仅由小写英文字母组成


AC代码:

bool areAlmostEqual(string s1, string s2) {
if(s1==s2) return true;
int n=s1.size(),m=s2.size();
if(n!=m) return false;
for(int i=0;i<n;i++)
for(int j=i+1;j<n;j++)
{
swap(s1[i],s1[j]);
if(s1==s2) return true;
swap(s1[i],s1[j]);
}
return false;
}



1791. 找出星型图的中心节点


题目描述:

有一个无向的 星型 图,由 n 个编号从 1 到 n 的节点组成。星型图有一个 中心 节点,并且恰有 n - 1 条边将中心节点与其他每个节点连接起来。

给你一个二维整数数组 edges ,其中 edges[i] = [ui, vi] 表示在节点 ui 和 vi 之间存在一条边。请你找出并返回 edges 所表示星型图的中心节点。

(对于一个星形图,任意两边,必定有一个重复的端点,而这个点就是我们要找的中心点。)


样例:

输入:edges = [[1,2],[5,1],[1,3],[1,4]]
输出:1


数据约束:

3 <= n <= 105
edges.length == n - 1
edges[i].length == 2
1 <= ui, vi <= n
ui != vi
题目数据给出的 edges 表示一个有效的星型图


AC代码:


class Solution {
public:
int cnt[100010];
int findCenter(vector<vector<int>>& edges) {
int a=edges[0][0],b=edges[0][1];
if(a==edges[1][0] || a==edges[1][1]) return a;
else return b;
}
};



1792. 最大平均通过率


题目描述:

一所学校里有一些班级,每个班级里有一些学生,现在每个班都会进行一场期末考试。给你一个二维数组 classes ,其中 classes[i] = [passi, totali] ,表示你提前知道了第 i 个班级总共有 totali 个学生,其中只有 passi 个学生可以通过考试。

给你一个整数 extraStudents ,表示额外有 extraStudents 个聪明的学生,他们 一定 能通过任何班级的期末考。你需要给这 extraStudents 个学生每人都安排一个班级,使得 所有 班级的 平均 通过率 最大 。

一个班级的 通过率 等于这个班级通过考试的学生人数除以这个班级的总人数。平均通过率 是所有班级的通过率之和除以班级数目。

请你返回在安排这 extraStudents 个学生去对应班级后的 最大 平均通过率。与标准答案误差范围在 10-5 以内的结果都会视为正确结果。


样例:

输入:classes = [[1,2],[3,5],[2,2]], extraStudents = 2
输出:0.78333
解释:你可以将额外的两个学生都安排到第一个班级,平均通过率为 (3/4 + 3/5 + 2/2) / 3 = 0.78333 。


数据约束:

1 <= classes.length <= 105
classes[i].length == 2
1 <= passi <= totali <= 105
1 <= extraStudents <= 105


思路:

怎样能使平均值最大?给定一个班级,通过人数为 a,总人数为 b,则通过率为 a/b。若加了一个尖子生到这个班级,则通过人数变为 a+1,总人数为 b+1,通过率为

 (a+1) /(b+1)。令 dt =  (a+1) /(b+1) - a/b 表示把尖子生加到这个班能增加的通过率。最后的目标是使总通过率最大,那么每个尖子生应该加到能使通过率增加量dt最大的那个班,这样最后的总通过率才最大。


AC代码:

 double maxAverageRatio(vector<vector<int>>& classes, int extraStudents) {
struct node
{
double dt;
int a,b;
bool operator < (const node& v) const{
return dt<v.dt;
}
};
priority_queue<node> heap;
double sum=0;
for(auto& c:classes)
{
int a=c[1],b=c[0];
sum+=(double)b/a;
heap.push({(double)(a-b)/(a*(a+1.0)),a,b});
}
while(extraStudents -- )
{
node t=heap.top();
heap.pop();
int a=t.a+1,b=t.b+1;
sum+=t.dt;
heap.push({(double)(a-b)/(a*(a+1.0)),a,b});
}
return sum/classes.size();
}


1793. 好子数组的最大分数



题目描述:

给你一个整数数组 nums (下标从 0 开始)和一个整数 k 。

一个子数组 (i, j) 的 分数 定义为 min(nums[i], nums[i+1], ..., nums[j]) * (j - i + 1) 。一个 好 子数组的两个端点下标需要满足 i <= k <= j 。

请你返回 好 子数组的最大可能 分数 。


样例:

输入:nums = [1,4,3,7,4,5], k = 3
输出:15
解释:最优子数组的左右端点下标是 (15) ,分数为 min(4,3,7,4,5) * (5-1+1) = 3 * 5 = 15 。


数据约束:

1 <= nums.length <= 105
1 <= nums[i] <= 2 * 104
0 <= k < nums.length


思路:

模板题:

(代码直接粘过来就行……模板还得使劲背呀,大佬们5分钟写完4道题真的太强了。)

对于每个数,找一遍左边第一个比它小的数的位置,右边第一个比它小的数的位置,人后区间长度乘以这个数就行了。


AC代码:

int maximumScore(vector<int>& nums, int k) {
int n=nums.size();
vector<int> h(n+2,-1),l(n+2),r(n+2),stk(n+2);
for(int i=1;i<=n;i++) h[i]=nums[i-1];
int tt=0;
stk[0]=0;
for(int i=1;i<=n;i++)
{
while(h[stk[tt]] >= h[i]) tt--;
l[i]=stk[tt];
stk[++tt]=i;
}
tt=0;
stk[0]=n+1;
for(int i=n;i>=1;i--)
{
while(h[stk[tt]] >= h[i]) tt--;
r[i]=stk[tt];
stk[++tt]=i;
}
int sum=0;
k++;
for(int i=1;i<=n;i++)
{
if(r[i]>k && l[i]<k) sum=max(sum,h[i]*(r[i]-l[i]-1));
}
return sum;
}

文章转载自fighting小王子,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论