Leetcode 周赛#200 题解
1535 找出数组游戏的赢家 #模拟+优化
题目链接
题意
给你一个由 不同 整数组成的整数数组 arr 和一个整数 k(\(1\leq k\leq1e9\)) 。每回合游戏都在数组的arr[0] 和 arr[1]之间进行,比较两者大小,较大的元素将会取得这一回合的胜利并保留在位置 0 ,较小者移至数组的末尾。当一个整数赢得 k 个连续回合时,游戏结束,该整数就是比赛的赢家,现求该整数
样例

因此将进行 4 回合比赛,其中 5 是赢家,因为它连胜 2 回合
分析
观察\(k\)的数据范围,直接模拟肯定过不了。我们猜想当遍历到数组末端时,赢家已经确定下来。
我们先假定\(k<\)数组长度,设存在\(cur<pos\),\(a[cur]>a[0, pos-1]\)且\(a[cur]<a[pos]\)。现有两种情况:
- 如果\(cur<\)数组长度\(-1\)且获胜整数的连胜达到\(k\)时,毫无疑问直接返回\(arr[cur]\)
- 如果\(cur=\)数组长度但是连胜次数还没到达\(k\),此时,我们可以知道\(arr[cur]\)一定比\(arr[0, cur-1]\)大,又因为\(cur\)到达数组长度,可以推出\(arr[cur]\)为数组中的最大值,继续比较搬过来的元素,将没有意义。故也是\(arr[cur]\)
当\(k\ge\)数组长度,要连胜\(k\)次,至少比较完\(arr\)数组所有元素一轮,那要一轮都能够取胜且\(arr\)无重复数字,可推出只有\(arr\)的\(max\)才能满足连胜\(k\)局
总的来说,我并不需要模拟"较小的整数移至数组的末尾"的操作,\(O(n)\)即可
class Solution {
public:
int getWinner(vector<int>& arr, int k) {
int len = arr.size();
int cur = 0;
int cnt = 0;
for (int pos = 1; pos < len; pos++) {
if (arr[cur] > arr[pos]) {
cnt++;
}
else {
cur = pos;
cnt = 1;
}
if (cnt == k)
return arr[cur];
}
return arr[cur];
}
};
1536 排布二进制网格的最少交换次数 #贪心
题目链接
题意
给定\(n\times n\)的二进制网格\(grid\),每次操作可选择网格的相邻两行进行交换。
现要将给定网格转化为满足主对角线以上(从 \((1, 1)\) 到 \((n, n)\))的格子全为 0的网格 ,要求使网格满足要求的最少操作次数。若无法使网格符合要求,返回 -1
样例

分析
那我们肯定要先将\(grid\)抽出关键信息,转化为一维数组\(a\),\(a[i]\)代表第\(i\)行存0的个数(注意是从右到左,一旦碰到1便停止计入)。
在赛场上,观察到最终的\(grid\),从第\(0\)行到第\(n-1\)行,0的个数几乎是““单调减少”。要将无序个数,转化为有序个数\(\Longrightarrow\) 排序消除逆序对?然而这并非是最优解,而且写着写着,会发现越来越多的数据得到的答案不符合最优解,比如{\(4, 1, 2, 3, 4\)},显然我们是无需再将末尾的4交换到1号位置的。
我们不应该只比较行与行之间的相对大小,更要注意到第\(i\)行所需的0个数不小于\((n-i-1)\),我们从第0行开始遍历,一旦发现某一行满足条件,就无需再管当前行。检查下一行,如果不满足条件,我们要向下寻找能够满足条件且是第一个的(即该行0个数大于等于检查行所需0个数),并把它交换上来。交换的同时统计操作次数,当遍历到最底行时便得到答案。
class Solution {
public:
int minSwaps(vector<vector<int>>& grid) {
int zero[205] = { 0 }, len = grid.size();
for (int i = 0; i < len; i++) {
int cnt = 0;
for (int j = grid[i].size() - 1; j >= 0; j--) {
if (grid[i][j] == 0) cnt++;
else break;
}
zero[i] = cnt;
}
int ans = 0;
for (int i = 0; i < len; i++) { //枚举第i行
if (zero[i] >= len - i - 1) continue;
int now = len - i - 1; //条件所需个数
int pos = i;
for (int j = i + 1; j < len; j++) {
if (zero[j] >= now) {
pos = j; break;
}
}//pos存第一个满足条件的那一行
if (pos == i) return -1;
for (int j = pos; j >= i+1; j--) {
swap(zero[j], zero[j - 1]);
ans++;
}
}
return ans;
}
};
1537 最大得分 #分段统计极值 #双指针
题目链接
题意
给定两个有序且数组内元素互不相同的数组``nums1 和nums2`。一条合法路径定义如下:
选择数组 nums1 或者 nums2 开始遍历(从下标 0 处开始)。
- 从左到右遍历当前数组。
- 若遇到了 nums1 和 nums2 中都存在的值,那么可以切换路径到另一个数组对应数字处继续遍历(但在合法路径中重复数字只会被统计一次)。
- 得分定义为合法路径中不同数字的和。
现要求所有可能合法路径中的最大得分,并将它对 10^9 + 7 取余后返回。
样例

结果为\(30\)
分析
自己写的时候想得复杂了,利用双指针,比较两指针指向元素大小,先指向小元素的指针前进。直到两指针指向元素相等,再比较两个数组的前一条段的和,获得局部极大值,累加进答案。当有一指针到达数组末端时,将有剩余元素的数组继续一路迭代累加,最后再比较一次极大值,计入答案取模。注意,由于要比较局部的极大值,如果一边做加法一边取模会影响比较结果,且long long能够承受这个数据范围,故只需在最后取模一次即可。

typedef long long ll;
class Solution {
private: const int MOD = 1e9 + 7;
public:
ll mymax(ll& a, ll& b) {
return a > b ? a : b;
}
int maxSum(vector<int>& nums1, vector<int>& nums2) {
int len1 = nums1.size(), len2 = nums2.size();
int p1 = 0, p2 = 0;
ll sum1 = 0, sum2 = 0;
ll ans = 0;
while (p1 < len1 && p2 < len2) {
if (nums1[p1] > nums2[p2]) {
sum2 = (sum2 + nums2[p2]);
p2++;
}
else if (nums1[p1] < nums2[p2]) {
sum1 = (sum1 + nums1[p1]);
p1++;
}
else {
ans = (ans + mymax(sum1, sum2));
ans = (ans + nums1[p1]);
sum1 = sum2 = 0;
p1++; p2++;
}
}
while (p1 < len1) sum1 = (sum1 + nums1[p1++]);
while (p2 < len2) sum2 = (sum2 + nums2[p2++]);
ans = (ans + mymax(sum1, sum2)) % MOD;
return ans;
}
};
Leetcode 周赛#200 题解的更多相关文章
- Leetcode 周赛#202 题解
本周的周赛题目质量不是很高,因此只给出最后两题题解(懒). 1552 两球之间的磁力 #二分答案 题目链接 题意 有n个空篮子,第i个篮子位置为position[i],现希望将m个球放到这些空篮子,使 ...
- LeetCode周赛#204 题解
1566. 重复至少 K 次且长度为 M 的模式 #模拟 题目链接 题意 给定正整数数组 arr,请你找出一个长度为 m 且在数组中至少重复 k 次的模式. 模式 是由一个或多个值组成的子数组(连续的 ...
- LeetCode周赛#203 题解
1561. 你可以获得的最大硬币数目 #贪心 题目链接 题意 有 3n 堆数目不一的硬币,你和你的朋友们打算按以下方式分硬币: 每一轮中,你将会选出 任意 3 堆硬币(不一定连续). Alice 将会 ...
- Leetcode 周赛#201 题解
1545 找出第N个二进制字符串的第K位 #分治 题目链接 题意 给定正整数\(n(\leq 20)\)与\(k\),二进制串\(S_n\)形成规则有: \(S_1 = "0"\) ...
- LeetCode双周赛#33 题解
5480. 可以到达所有点的最少点数目 #贪心 题目链接 题意 给定有向无环图,编号从0到n-1,一个边集数组edges(表示从某个顶点到另一顶点的有向边),现要找到最小的顶点集合,使得从这些点出发, ...
- Leetcode 双周赛#32 题解
1540 K次操作转变字符串 #计数 题目链接 题意 给定两字符串\(s\)和\(t\),要求你在\(k\)次操作以内将字符串\(s\)转变为\(t\),其中第\(i\)次操作时,可选择如下操作: 选 ...
- 【Leetcode周赛】从contest-111开始。(一般是10个contest写一篇文章)
Contest 111 (题号941-944)(2019年1月19日,补充题解,主要是943题) 链接:https://leetcode.com/contest/weekly-contest-111 ...
- 【Leetcode周赛】从contest-41开始。(一般是10个contest写一篇文章)
Contest 41 ()(题号) Contest 42 ()(题号) Contest 43 ()(题号) Contest 44 (2018年12月6日,周四上午)(题号653—656) 链接:htt ...
- 【Leetcode周赛】从contest-51开始。(一般是10个contest写一篇文章)
Contest 51 (2018年11月22日,周四早上)(题号681-684) 链接:https://leetcode.com/contest/leetcode-weekly-contest-51 ...
随机推荐
- react-native 常见问题
1.webpack使用babel-loader后编译报错 报错ERROR in ./entry.js Module build failed: SyntaxError: /Users/yixin/De ...
- Redis---04Redis持久化
一.RDB(保存的是数据) 1.概念: 在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是Snapshot快照,它恢复时是将快照文件直接读到内存里. 2.执行过程: Redis会单独创建(fork ...
- 国云数据:中国版的Snowflake,国内数据中台领导者
[股神巴菲特加持,今年最受关注美股IPO ] 这段时间, 由股神巴菲特54年来首次打新的美股IPO公司Snowflake迅速得到业界重点关注.Snowflake已于2020年9月16日正式上市,发行价 ...
- MongoDB 数据备份和恢复 --- MongoDB基础用法(七)
数据备份 在Mongodb中我们使用mongodump命令来备份MongoDB数据.该命令可以导出所有数据到指定目录中. mongodump命令可以通过参数指定导出的数据量级转存的服务器. mongo ...
- BIO编程
在实际的工作开发中,传统的模型有client/service模型.client端和service端要进行通信的话,有一种套接字的方式.传统的socket编程,包含一个socket服务端和一到多个soc ...
- 初识ABP vNext(12):模块的独立运行与托管
Tips:本篇已加入系列文章阅读目录,可点击查看更多相关文章. 目录 前言 开始 模块运行 动态 C# API 客户端 最后 前言 很久没更新这个系列...之前的章节中讲到ABP的模块是可以独立运行的 ...
- LuoguP3615 如厕计划
题面 现有两个厕所,一个女士专用,一个通用,给出\(2*n\)个排成一列的人的性别 每人如厕需要一分钟,假如女厕是空的,女生中最靠前的可以直接进入. 需要通过调换顺序使得所有人都上完厕所最后的时间为n ...
- python爬虫使用xpath解析页面和提取数据
XPath解析页面和提取数据 一.简介 关注公众号"轻松学编程"了解更多. XPath即为XML路径语言,它是一种用来确定XML(标准通用标记语言的子集)文档中某部分位置的语言.X ...
- 在pandas中使用pipe()提升代码可读性
1 简介 我们在利用pandas开展数据分析时,应尽量避免过于碎片化的组织代码,尤其是创建出过多不必要的中间变量,既浪费了内存,又带来了关于变量命名的麻烦,更不利于整体分析过程代码的可读性,因此以流水 ...
- day85:luffy:购物车根据有效期不同切换价格&购物车删除操作&价格结算&订单页面前戏
目录 1.购物车有效期切换 2.根据有效期不同切换价格 3.购物车删除操作 4.价格结算 5.订单页面-初始化 1.购物车有效期切换 1.关于有效期表结构的设计 1.course/models.py ...