1848. 到目标元素的最小距离

时间复杂度O(n)

start 向两端寻找 target,找到的第一个目标元素即最近的。

class Solution {public:int getMinDistance(vector<int>& nums, int target, int start) {for (int i = 0, n = nums.size(); i < n; i++) {if ((start+i < n && nums[start+i] == target) || (start-i >= 0 && nums[start-i] == target)) {return i;}}return 0;}
};

1849. 将字符串拆分为递减的连续值

知识点递归

时间复杂度O(n^2)

因为两个数字相差必须是1,所以只要前一个数字确定了,当前数字的值就确定了。

首先,枚举第一个数字的长度,一旦长度确定了,值就确定了,后续数字的值也就确定了。然后按值尝试分割字符串即可。

需要注意的是,如果直接把s转换为数字,有可能超出int64的取值范围。但是因为要将s分割成两个数字,所以第一个数字的上限是999,999,999,9

class Solution {public:int64_t toNumber(const std::string &s, int l, int r) {int64_t anw = 0;while(l <= r) {anw *= 10;anw += (s[l] - '0');l++;}return anw;}bool check(const std::string &s, int pos, int64_t pre) {if (pos == s.size()) {return true;}for (int i = pos; i < s.size(); i++) {int64_t val = toNumber(s, pos, i);if (val == pre-1) {if (check(s, i+1, val)) {return true;}} else if (val >= pre) {return false;}}return false;}bool splitString(string s) {if (s.size() <= 1) {return false;}int n = s.size()-1;int64_t limit = 1L<<40;for (int i = 0; i < n; i++) {int64_t val = toNumber(s, 0, i);if (val > limit) {return false;}if (check(s, i+1, val)) {return true;}}return false;}
};

1850. 邻位交换的最小次数

知识点next_permutation

时间复杂度O(n^2)

设第 k 个最小妙数为target,如果能构造出 target,则求最小次数是很简单的。那问题变成了如何构造 target。

竞赛时可以借助库函数 next_permutation 构造target。不过面试时还是要能手写next_permutation。接下来简单介绍下next_permutation的实现。

设有字符串s,及s的下一个排列 p,两者长度为n,最长公共前缀的长度为 c。则必有:

  • 构成 p[c .. n)s[c .. n) 的字符集合相同。
  • p[c]s[c+1 .. n) 中,大于s[c]的最小字符。
  • p[c+1 .. n) 升序排列。

那么将 s 构造为 p,只需要三步:

  • 找到s中满足s[i] < s[i+1] 的最大的i,该 i 即为 c
  • 找到 s[c+1 .. n) 中大于s[c]的最小字符s[t],并将两者交换。
  • s[c+1 .. n] 升序排列。

现在我们可以重复k次上述构造过程,得到target,然后模拟题目的交换过程并计数,即可得到答案。

class Solution {public:int getMinSwaps(string num, int k) {cout << s << endl;string old = num;int end = num.size()-1;while(k--) {for (int i = end; i >= 1; i--) {if (num[i-1] < num[i]) {int l = i-1;while(i+1 <= end && num[l] < num[i+1]) {i++;}swap(num[l], num[i]);reverse(num.begin() + l + 1, num.end());break;}}}int anw = 0;for (int i = end; i >= 0; i--) {if (num[i] != old[i]) {int j = i-1;while(old[j] != num[i]) {j--;}anw += i-j;while(j < i) {swap(old[j], old[j+1]);j++;}}}return anw;}
};

1851. 包含每个查询的最小区间

知识点离线处理

时间复杂度O(n*lgn)

设有 left, right 分别存储了将interval按左右端点排序之后的结果。

设当前正在被处理的询问为 query

lp 为满足 left[lp][0] 不超过 query 的最大坐标,即left[0 .. lp] 中所有区间的左端点都在query左边或与query相等,而其他区间的左端点都在query右边。

rp 为满足 right[rp][1] 小于 query 的最大坐标,及right[0 .. rp] 中的所有区间的右端点都在query的左边,而其他区间的右端点都在query的右边或与query相等。

换言之,在left[0 .. lp]中而不在right[0 .. rp]中的最短的区间的长度,即为query的答案。

在代码实现上,可以用一个 multiset 来维护这部分数据:

  • 首先对于当前的query,先找到lp,将left[0 .. lp]中所有区间的长度都插入到容器中。
  • 然后找到rp,将right[0 .. rp]中所有区间的长度都从容器中删除。
  • 容器中最小的元素即为答案,如果容器为空,则答案不存在。

另外,如果所有的查询 queries 是有序的,不难发现,随着query的增大,lprp是单调递增的,也就是说,没必要每次都从0开始寻找lprp并维护容器。而是可以从前一次查询的基础上,继续维护容器内的元素。

class Solution {public:vector<int> minInterval(vector<vector<int>>& l, vector<int>& queries) {multiset<int> len;auto r = l;sort(l.begin(), l.end(), [](const auto &lhs, const auto &rhs) { return lhs[0] < rhs[0]; });sort(r.begin(), r.end(), [](const auto &lhs, const auto &rhs) { return lhs[1] < rhs[1]; });vector<vector<int>> query;for (int i = 0; i < queries.size(); i++) {query.push_back(std::vector<int>{queries[i], i});}sort(query.begin(), query.end(), [](const auto &lhs, const auto &rhs) { return lhs[0] < rhs[0];});int lp = 0, rp = 0;vector<int> anw(query.size(), 0);for (auto q : query) {while (lp < l.size() && l[lp][0] <= q[0]) {len.insert(l[lp][1] - l[lp][0] + 1);lp++;}while (rp < r.size() && r[rp][1] < q[0]) {auto it = len.find(r[rp][1] - r[rp][0] + 1);len.erase(it);rp++;}anw[q[1]] = len.empty() ? -1 : *len.begin();}return anw;}
};

力扣周赛 239 题解相关推荐

  1. 20210503:力扣第239周周赛题解

    力扣第239周周赛 题目 思路与算法 代码实现 写在最后 题目 到目标元素的最小距离 将字符串拆分为递减的连续值 邻位交换的最小次数 思路与算法 到目标元素的最小距离:直接遍历,维护结果就行. 将字符 ...

  2. 力扣周赛310场题解

    力扣周赛310场题解 前言 6176. 出现最频繁的偶数元素 6177. 子字符串的最优划分 前言 今天参加了力扣的第310场周赛,也是感觉到了这周的题的一个难度,有些题有想法,但是实际上让我去写的时 ...

  3. 第 256 场力扣周赛(状态压缩+dp,二进制子序列的动规、940)

    第 256 场力扣周赛 有事没做,来看一下题 5854. 学生分数的最小差值 题目描述 给你一个 下标从 0 开始 的整数数组 nums ,其中 nums[i] 表示第 i 名学生的分数.另给你一个整 ...

  4. 第二次力扣周赛:排名149 / 2046;在完赛边缘打转(总结了5点,实力还不够)

    前言: 上午10:30 - 12:00 第二次力扣周赛,最后一题也写完了,但是没有通过.完成了 3 / 4 的题,排名 149 / 2046. 赛题:https://leetcode-cn.com/c ...

  5. 第 304 场力扣周赛

    1.Introduction 平常做代码题目较少,今天迟迟不能入睡,我思考了下,确实有很大概率,对十年内做的目标,有很大可能不能实现.于是做了几道题勉强让自己心安.一边喝着牛栏山壮精神,一边写Leet ...

  6. 第 270 场力扣周赛

    第一百一十二天 --- 第 270 场力扣周赛 题目一 思路:直接模拟 细节 代码 附加 题目二 思路 细节 代码 题目一 力扣:2094. 找出 3 位偶数 思路:直接模拟 1.因为构造所有三位数, ...

  7. 第 254 场力扣周赛(KMP、贪心、快速幂、二分+多源bfs、并查集 + 时光倒流)

    第 254 场力扣周赛 稀里糊涂双眼双眼惺忪的做了三道,错了4次...还是600来名 5843. 作为子字符串出现在单词中的字符串数目 题目描述 给你一个字符串数组 patterns 和一个字符串 w ...

  8. LeetCode 第 58 场力扣夜喵双周赛(动态规划、马拉车算法,前后缀处理)/ 第 253 场力扣周赛(贪心,LIS)

    第 58 场力扣夜喵双周赛 两道600多 5193. 删除字符使字符串变好 题目描述 一个字符串如果没有 三个连续 相同字符,那么它就是一个 好字符串 . 给你一个字符串 s ,请你从 s 删除 最少 ...

  9. 【力扣周赛】第342场周赛

    [力扣周赛]第342场周赛 6387:计算列车到站时间 题目描述 解题思路 6391:倍数求和 题目描述 解题思路 6390:滑动子数组的美丽值 题目描述 解题思路 6392:使数组所有元素变成1的最 ...

最新文章

  1. 【AI项目商务合作】图像拼接
  2. 认识与入门 Markdown
  3. SCPPO(五):解决MVC中Json传输数据量问题
  4. 如何在Ubuntu里安装Helm 1
  5. win10升级后ctrl+shift+f失效了(zend studio)问题解决
  6. photoshop基础视频教程 [4G]
  7. JAVA小项目-银行管理系统(图形化界面)2-开户与挂失
  8. Ubuntu18.04安装OBS Studio
  9. python中复数表达形式_在Python中实现复数比较?
  10. 七印部落送给大家的《启示录》
  11. 逻辑综合重点解析55题(Design Compiler篇)
  12. Android如何计算View的深度
  13. 阿里----OSS对象存储服务
  14. python的简单使用_用python简单处理图片
  15. i31115g4和r34300u哪个好
  16. 如何在arxiv上面发论文
  17. 腾讯推出世界最强人脸识别 准确率99.8%;微软在慕尼黑设立欧洲首个物联网实验室 | IoT黑板报...
  18. C++编程(二):CURL错误码及含义
  19. C++实现迪杰斯特拉(dijkstra)算法(最小生成树)
  20. python樱花手绘_Python 手绘风格可视化神包:cutecharts

热门文章

  1. Lab: Cross-site WebSocket hijacking:跨站WebSocket劫持
  2. 以EV录屏为例详细讲解-录屏,开直播的全局配置
  3. 【例16 Java从键盘读入学生成绩,找出最高分,并输出学生成绩等级】
  4. WIN7 | 网络正常,但网页打不开 | 远程计算机或设备不接受连接
  5. 零跑汽车股价再创数据新高
  6. 服务器购买之后要做什么(二)
  7. 时间戳服务器作用,时间戳服务器
  8. UDS之浅谈14 服务
  9. ★Kali信息收集★8.Nmap :端口扫描
  10. 图卷积神经网络(GCN)综述与实现(PyTorch版)