5554. 能否连接形成数组

题目链接

题意

给定整数数组 arr ,其中每个整数互不相同 。另有一个由整数数组构成的数组 pieces,其中的整数也互不相同 。请以 任意顺序 连接 pieces 中的数组以形成 arr 。但是,不允许 对每个数组内部 pieces[i] 中的整数重新排序。若可连接 pieces 中的数组形成 arr ,返回 true ;否则,返回 false

样例

分析

如果遍历arr每个元素找到其对应的pieces[i]子数组,考虑的细节有很多。不妨遍历每个pieces[i]数组,以其子数组的首元素作为切入口,找到arr数组对应位置,再将pieces[i]这个子数组遍历完,如果无法遍历完又或者arr对应指针到达末端,则说明无法满足题目要求。

class Solution {
public:
bool canFormArray(vector<int>& arr, vector<vector<int>>& pieces) {
int tot = 0, i = 0;
for (; i < pieces.size(); i++){ //遍历每一组piece首元素,找到arr对应的位置。
int pos;
for (pos = 0; pos < arr.size(); pos++){
if(arr[pos] == pieces[i][0]) break;
}
if(pos == arr.size()) return false; //说明pieces存在arr没有的元素
for (int j = 0; j < pieces[i].size(); j++){ //继续深入该子数组
if(pieces[i][j] == arr[pos]) pos++;
else return false; //说明不连续
if(pos >= arr.size() && j + 1 < pieces[i].size()) //此时arr指针指向arr末端,但pieces子数组指针还没到达末端,说明不连续
return false;
}
}
return (i == pieces.size());
}
};

5555. 统计字典序元音字符串的数目 #组合数 #暴力搜索

题目链接

题意

给定整数 \(n(\le 50)\),请返回长度为 \(n\) 、仅由元音 (\(a, e, i, o, u\)) 组成且按 字典序排列 的字符串数量

字符串 \(s\) 按 字典序排列 需要满足:对于所有有效的 \(i\),\(s[i]\) 在字母表中的位置总是与 \(s[i+1]\) 相同或在 \(s[i+1]\) 之前。

分析

下面是我在比赛时交的暴搜版本(主要是因为数据规模不大),每次递归是枚举当前位置放置第\(i\)个元音字母且保证不超过上一个字母。

class Solution {
private:
int depest = 0;
public:
int DFS(int depth, int pre){
if(depth == depest) return 1;
int ans = 0;
for (int i = 1; i <= pre; i++) ans += DFS(depth + 1, i);
return ans;
}
int countVowelStrings(int n) {
depest = n;
int ans = 0;
for (int i = 1; i <= 5; i++) ans += DFS(1, i);//从第i个元音字母出发
return ans;
}
};

仔细一想,其实我们直接用挡板法便能求出来。因为所求的字符串一定是按\(a\le e\le i\le o\le u\)的顺序的,不过每种元音字母的数量可以为\(0\)。由于隔板法需要保证每个箱子至少有一个球,那我们可以给每个元音字母分配一个虚拟的位置(即需要\(n+5\)个小球),插完隔板之后再将虚拟位置去掉即可。故答案即为\(C^{5-1}_{n+5-1}\)。

class Solution {
public:
int countVowelStrings(int n) {
return (n + 4) * (n + 3) * (n + 2) * (n + 1) / 24;
}
};

5556. 可以到达的最远建筑 #贪心

题目链接

题意

给定整数数组 heights ,表示建筑物的高度。另有一些bricks个砖块 和 ladders 梯子。

你从建筑物 0 开始出发,不断向后面的建筑物移动,当从建筑物 i 移动到建筑物 i+1(下标 从 0 开始 )时:

  • 若当前建筑物的高度 大于或等于 下一建筑物的高度,则不需要梯子或砖块。
  • 如果当前建筑的高度 小于 下一个建筑的高度,您可以使用 一架梯子 或 (h[i+1] - h[i]) 个砖块

如果以最佳方式使用给定的梯子和砖块,返回你可以到达的最远建筑物的下标(下标 从 0 开始 )。

分析

感谢@零神的题解,讲解得十分好。

我试着用自己的语言去总结下吧,题目中的梯子可以爬无限高的楼,设梯子数量为\(l\),出于贪心思想,我们一定会将所有的梯子用在前\(l\)大的楼层高度差Δ\(h\)。但是我们不可能即时确定下来这\(l\)个较大的Δ\(h\),因而需要用个小根堆去维护。

为什么用小根堆?因为每次到达新的楼时,判断新的Δ\(h\)是否比小根堆的堆顶(即第\(l\)大的Δ\(h\))还大,如果成立则应该将这个新的Δ\(h\)加入堆,并把原来的堆顶pop出来,交给砖块去跨越。

何时终止?当砖块的数量不足以解决新pop出来的Δ\(h\)时,算法即终止。

class Solution {
public:
int furthestBuilding(vector<int>& heights, int bricks, int ladders) {
priority_queue<int, vector<int>, greater<int>> myque; //小根堆放进梯子要爬的楼层差,并维护堆中最小的楼层差。
int brickSum = 0;
for (int i = 0; i + 1 < heights.size(); i++){
int diff = heights[i + 1] - heights[i];
if(diff < 0) continue;
myque.push(diff);
if(myque.size() > ladders){
brickSum += myque.top(); //交给砖块解决
myque.pop();
}
if(brickSum > bricks) //砖块解决不了就终止
return i;
}
return heights.size() - 1;
}
};

5600. 第 K 条最小指令 #组合公式 #分治

题目链接

题意

Bob 站在单元格 (0, 0) ,想要前往目的地坐标 destination :(row, column) 。你可以为 Bob 提供导航 指令 来帮助他到达目的地 destination

指令 用字符串表示,其中每个字符:'H' ,意味着水平向右移动;'V' ,意味着竖直向下移动。

能够为 Bob 导航到目的地 destination 的指令可以有多种,例如,如果目的地 destination 是 (2, 3),"HHHVV", "HHVHV", "HHVVH", "HVHHV", ...都是有效 指令 。然而,Bob 想要遵循 按字典序排列后的第 k 条最小指令 (从1)的导航前往目的地 destination 。例如,Bob需要第3条最小,对应指令即为"HHVVH"

给定整数数组 destination 和一个整数 k ,现要返回这个按字典序排列后的第 k 条最小字符串指令 。

分析

再次感谢@零神的题解orz…

设需要放入\(h\)个'H'和\(v\)个'V',题目要求第\(k\)小,那么我们可以从高位到低位,不断淘汰出前\(k\)小的串,具体如下:

我们考虑当前最高位pos,应该放'H'还是'V'。假设放'V',那么所有pos位为'H'的字符串都会被淘汰掉,且总共有\(cur = C^{h-1}_{h+v-1}\)个被淘汰掉。我们判断下\(cur\)个串是否超出\(k\):

  • 若\(k > cur\),说明最高位放置'V',也没有将足够多的串给淘汰掉,因而我们接下来要继续在\(pos+1\)位放置'V'去淘汰剩余的\(cur-k\)个串(该串此时只允许放\(h\)个'H'、\(v-1\)个'V')。
  • 若\(k<cur\),说明淘汰过多,最高位应该放置'H',即淘汰不成功,考虑\(pos+1\)位放置'V'去淘汰剩余的\(k\)个串(该串此时只允许放\(h-1\)个'H'、\(v\)个'V'

注意,我们可能要计算\(C^{14}_{29}\),先做乘法运算时会超过\(long\ long\)范围,因此需要用递推式预先处理组合公式。

class Solution {
public:
string kthSmallestPath(vector<int>& destination, int k) {
int v = destination[0], h = destination[1];
int comb[35][35] = {0};
comb[0][0] = 1;
for(int i = 1; i <= (v + h); i++){
comb[i][0] = comb[i][i] = 1;
for(int j = 1; j < i; j++)
comb[i][j] = comb[i - 1][j - 1] + comb[i - 1][j];
}
string ans = "";
int sum = 0, posMax = (v + h);
for (int pos = 1; pos <= posMax; pos++){
if(h >= 1){ //保证数组下标不为负
int cur = comb[v + h - 1][h - 1]; //假如当前最高位置'V',相当于将所有最高位为'H'的字符串给淘汰掉了
if(k > cur) { //说明淘汰得还不够
k -= cur;
v--;
ans += "V";
}
else { //淘汰过高
h--; //最高位只能先放下'H'
ans += "H";
}
}
else{ //说明h已经用完了,只能放v了
ans += "V";
v--;
}
}
return ans;
}
};

LeetCode周赛#213的更多相关文章

  1. 【Leetcode周赛】从contest-111开始。(一般是10个contest写一篇文章)

    Contest 111 (题号941-944)(2019年1月19日,补充题解,主要是943题) 链接:https://leetcode.com/contest/weekly-contest-111 ...

  2. 拼写单词[哈希表]----leetcode周赛150_1001

    题目描述: 给你一份『词汇表』(字符串数组) words 和一张『字母表』(字符串) chars. 假如你可以用 chars 中的『字母』(字符)拼写出 words 中的某个『单词』(字符串),那么我 ...

  3. 【Leetcode周赛】从contest-41开始。(一般是10个contest写一篇文章)

    Contest 41 ()(题号) Contest 42 ()(题号) Contest 43 ()(题号) Contest 44 (2018年12月6日,周四上午)(题号653—656) 链接:htt ...

  4. 【Leetcode周赛】从contest-51开始。(一般是10个contest写一篇文章)

    Contest 51 (2018年11月22日,周四早上)(题号681-684) 链接:https://leetcode.com/contest/leetcode-weekly-contest-51 ...

  5. 【Leetcode周赛】从contest-71开始。(一般是10个contest写一篇文章)

    Contest 71 () Contest 72 () Contest 73 (2019年1月30日模拟) 链接:https://leetcode.com/contest/weekly-contest ...

  6. 【Leetcode周赛】从contest-81开始。(一般是10个contest写一篇文章)

    Contest 81 (2018年11月8日,周四,凌晨) 链接:https://leetcode.com/contest/weekly-contest-81 比赛情况记录:结果:3/4, ranki ...

  7. 【Leetcode周赛】从contest-91开始。(一般是10个contest写一篇文章)

    Contest 91 (2018年10月24日,周三) 链接:https://leetcode.com/contest/weekly-contest-91/ 模拟比赛情况记录:第一题柠檬摊的那题6分钟 ...

  8. 【Leetcode周赛】从contest-121开始。(一般是10个contest写一篇文章)

    Contest 121 (题号981-984)(2019年1月27日) 链接:https://leetcode.com/contest/weekly-contest-121 总结:2019年2月22日 ...

  9. 【Leetcode周赛】从contest1开始。(一般是10个contest写一篇文章)

    注意,以前的比赛我是自己开了 virtual contest.这个阶段的目标是加快手速,思考问题的能力和 bug-free 的能力. 前面已经有了100个contest.计划是每周做三个到五个cont ...

随机推荐

  1. oracle 查询数据库锁及锁处理

    1.数据库锁表查询语句: SELECT SESS.SID, SESS.SERIAL#, LO.ORACLE_USERNAME, LO.OS_USER_NAME, AO.OBJECT_NAME 被锁对象 ...

  2. k8s各组件启动时, -v参数指定的日志级别

    k8s 相关组件启动时 -v参数指定的日志级别 --v=0 Generally useful for this to ALWAYS be visible to an operator. --v=1 A ...

  3. 运行Apache时出现the requested operation has failed

    在修改自己主机E:\wamp\apache\conf中的httpd.conf中的站点位置后,重新运行Apache时,出现对话框提示"the requested operation has f ...

  4. re模块,判断某行/某字符是否存在

    import re ##判断行是否存在def get_need_line(): ## 获取有用信息行 with open('task.log',mode="r") as f: fo ...

  5. 03_ubuntu samba 安装配置

    03_ubuntu samba 安装配置 安装samba sudo apt install samba 修改samba配置文件 sudo vim /etc/samba/smb.conf [share] ...

  6. Linux 环境下 C++ 的开发编译

    Linux环境下C++程序的开发编译学习笔记 环境:vmware 运行下的Ubuntu 16.04 姓名:谢津 时间:2018/5/24 内容:1)vim的安装及配置:2)第一个C++程序的编写与编译 ...

  7. 833. Find And Replace in String —— weekly contest 84

    Find And Replace in String To some string S, we will perform some replacement operations that replac ...

  8. 使用docker 部署codis

    使用docker 部署codis 原文地址:https://www.jianshu.com/p/85e72ae6fec3 codis的架构图 1.zookeeeper,用于存放统一配置信息和集群状态 ...

  9. 一些bug

    长期留坑 1.AC自动机多模式串匹配问题 对于要统计各个模式串在文本中的出现次数,对于每个当前节点不能直接暴力跳$fail$ 复杂可以退化到$O(n^2)$ $aaaaaa--aaa$可以卡掉 要将$ ...

  10. Magic Method

    Python 的 Magic Method 在 Python 中,所有以 "__" 双下划线包起来的方法,都统称为"魔术方法".比如我们接触最多的 __init ...