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. 从eclipse迁移到ideal

    个人用eclipse比较多,什么Luna,Neon,Mars.几乎每年都要研发出一个版本.目前所在的这家公司,维护的是一个10年的老项目,需求迭代频率比较高,业务代码臃肿而难理解,依赖关系不清晰,代码 ...

  2. ORB-SLAM3 Initializer.cpp函数解读

    作者: Liam 点击上方"计算机视觉工坊",选择"星标" 干货第一时间送达 构造函数 Initializer::Initializer(const Frame ...

  3. bat批处理常用脚本

    windows下有很多场景需要编写批处理来解决问题,跟定时任务相结合使用更佳. 1.创建文件,md,mkdir都可以进行文件创建 set AwrPath=D:\OracleTabChk if not ...

  4. .Net/.Net Core 的界面框架 NanUI 发布新版本啦!

    发布前感悟 NanUI 自从上一次更新 NanUI 0.7 已经过去大半年,B站和头条的教学视频也只制作到了第二集. 有朋友悄悄问我是不是发生什么事故我删库跑路了所以那么长时间不更新项目不发布教程,当 ...

  5. 不停机不更新代码线上调试BUG的工具

    如果你有以下痛点,请你查看本文章: 1.我改的代码为什么没有执行到?难道是我没 commit?分支搞错了? 2.遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗? 3.线上遇到某个用户的 ...

  6. Java并发(一):线程

    目录 一.什么是线程 二.中断线程 三.线程状态 四.线程属性 前言: 本文将简单的介绍JAVA并发中的线程. 操作系统的多任务(multitasking):计算机在同一刻运行多个程序的能力,即并发. ...

  7. 找不到package

    在rosrun (前面要有roscore)显示 cannot find the package 只需要一次 永久有效 catkin _ws 是工作空间 rhl@rhl-Lenovo-G480:~$ e ...

  8. canvas基础[二]教你编写贝塞尔曲线工具

    贝塞尔曲线 bezierCurveTo 在线工具 https://canvature.appspot.com/ [感觉这个好用一些] https://blogs.sitepointstatic.com ...

  9. Pandas_基础_全

    Pandas基础(全) 引言 Pandas是基于Numpy的库,但功能更加强大,Numpy专注于数值型数据的操作,而Pandas对数值型,字符串型等多种格式的表格数据都有很好的支持. 关于Numpy的 ...

  10. mdp文件-Chapter3-NPT.mdp

    mdp系列的第三篇,对NPT模拟中的mdp文件做一简单介绍. 先上代码 1 title = OPLS Lysozyme NPT equilibration 2 define = -DPOSRES ; ...