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. Linux配置和管理设备映射多路径multipath

    (一)多路径管理软件的由来 在企业中,服务器与存储通常是分开放置的,服务器上的硬盘通常用来安装操作系统和应用软件,业务数据则是存储在单独的存储设备上,那么,服务器与存储是如何连接的呢?根据存储协议,经 ...

  2. Java到处运行的基础之 Class 文件

    Java 实现一次编译到处运行的基础,来源于 Java 虚拟机屏蔽了操作系统的底层细节.使用 class 文件存储编译后的源程序,使得 Java 程序的编译与操作系统解耦.正是因为 Java clas ...

  3. 《Clojure编程》笔记 第1章 进入Clojure仙境

    目录 背景简述 第1章 进入Clojure仙境 1.1 基础概念 1.2 常用的一些符号 背景简述 本人是一个自学一年Java的小菜鸡,理论上跟大多数新手的水平差不多,但我入职的新公司是要求转Cloj ...

  4. MyBatis重要核心概念

    一.SqlSessionFactoryBuilder 从命名上可以看出,这个是一个 Builder 模式的,用于创建 SqlSessionFactory 的类.SqlSessionFactoryBui ...

  5. Android NurReaderView 阅读器 (字符串-.txt文件)

    有些地方还没配置好.2/3天后在更新.... 功能 支持字符串和<.txt>文件 文字自动分各个页面 支持从右到左-(从右边开始的语言.比如维吾尔语哈扎克语...外国的阿拉伯语等) 支持自 ...

  6. 7、Django之模型层第二篇:多表操作

    一 表关系回顾 在讲解MySQL时,我们提到,把应用程序的所有数据都放在一张表里是极不合理的. 比如我们开发一个员工管理系统,在数据库里只创建一张员工信息表,该表有四个字段:工号.姓名.部门名.部门职 ...

  7. jenkins配置邮件报错:501 mail from address must be same as authorization user

    jenkins配置文件的时候,遇到如下报错: 我的配置是这样的: 最后发现是jenkins url下面的系统管理员邮件地址没写,填写与用户名一致就可以了.

  8. CSS两列布局的多种方式

    两列布局(一侧固定宽度,一侧自适应),在工作中应该是经常使用到,可以说是前端基础了.这种两列布局的样式是我们在平时工作中非常常见的设计,同时也是面试中要求实现的高频题.很有必要掌握以备不时之需.这里总 ...

  9. Socket shutdown close简要分析

    shutdown 系统调用关闭连接的读数据通道  写数据通道 或者 读写数据通道: 关闭读通道:丢弃socket fd 读数据以及调用shutdown 后到达的数据: 关闭写通道:不同协议处理不同:t ...

  10. select模型(二 改进服务端)

    一. int select(int fds,fd_set *readfds,fd_set * writefds,fd_set * exceptfds,struct timeval * timeout) ...