LeetCode1482. 制作 m 束花所需的最少天数 / 剑指 Offer 32 . 从上到下打印二叉树I/II/III
Posted Zephyr丶J
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode1482. 制作 m 束花所需的最少天数 / 剑指 Offer 32 . 从上到下打印二叉树I/II/III相关的知识,希望对你有一定的参考价值。
LeetCode1482. 制作 m 束花所需的最少天数
2021.5.9每日一题
题目描述
给你一个整数数组 bloomDay,以及两个整数 m 和 k 。
现需要制作 m 束花。制作花束时,需要使用花园中 相邻的 k 朵花 。
花园中有 n 朵花,第 i 朵花会在 bloomDay[i] 时盛开,恰好 可以用于 一束 花中。
请你返回从花园中摘 m 束花需要等待的最少的天数。如果不能摘到 m 束花则返回 -1 。
示例 1:
输入:bloomDay = [1,10,3,10,2], m = 3, k = 1
输出:3
解释:让我们一起观察这三天的花开过程,x 表示花开,而 _ 表示花还未开。
现在需要制作 3 束花,每束只需要 1 朵。
1 天后:[x, _, _, _, _] // 只能制作 1 束花
2 天后:[x, _, _, _, x] // 只能制作 2 束花
3 天后:[x, _, x, _, x] // 可以制作 3 束花,答案为 3
示例 2:
输入:bloomDay = [1,10,3,10,2], m = 3, k = 2
输出:-1
解释:要制作 3 束花,每束需要 2 朵花,也就是一共需要 6 朵花。而花园中只有 5 朵花,无法满足制作要求,返回 -1 。
示例 3:
输入:bloomDay = [7,7,7,7,12,7,7], m = 2, k = 3
输出:12
解释:要制作 2 束花,每束需要 3 朵。
花园在 7 天后和 12 天后的情况如下:
7 天后:[x, x, x, x, _, x, x]
可以用前 3 朵盛开的花制作第一束花。但不能使用后 3 朵盛开的花,因为它们不相邻。
12 天后:[x, x, x, x, x, x, x]
显然,我们可以用不同的方式制作两束花。
示例 4:
输入:bloomDay = [1000000000,1000000000], m = 1, k = 1
输出:1000000000
解释:需要等 1000000000 天才能采到花来制作花束
示例 5:
输入:bloomDay = [1,10,2,9,3,8,4,7,5,6], m = 4, k = 2
输出:9
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-number-of-days-to-make-m-bouquets
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
二分查找的典型题型,因为所求时间具有二分性,小于这个时间不行,大于这个时间可以,所以可以用二分查找来找这个特定的时间
还有就是实现怎么判断在一个给定时间下,能形成花束,也简单
class Solution {
int[] bloomDay;
int m;
int k;
public int minDays(int[] bloomDay, int m, int k) {
//这个咋做来着,最小最大两个边界然后二分?
//然后判断该数能做几个花?写一下
this.bloomDay = bloomDay;
this.m = m;
this.k = k;
int l = bloomDay.length;
if(m * k > l)
return -1;
int left = Integer.MAX_VALUE;
int right = 0;
//找最小最大值
for(int i = 0; i < l; i++){
left = Math.min(left, bloomDay[i]);
right = Math.max(right, bloomDay[i]);
}
while(left < right){
int mid = (right - left) / 2 + left;
if(bloom(mid)){
right = mid;
}else{
left = mid + 1;
}
}
return left;
}
//判断能种几朵
public boolean bloom(int mid){
int count = 0;
int num = 0;
for(int i = 0; i < bloomDay.length; i++){
if(mid >= bloomDay[i]){
count++;
}
if(mid < bloomDay[i]){
count = 0;
}
if(count == k){
num++;
count = 0;
}
}
return num >= m;
}
}
剑指 Offer 32 - I. 从上到下打印二叉树
题目描述
从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。
例如:
给定二叉树: [3,9,20,null,null,15,7],
3
/ \\
9 20
/ \\
15 7
返回:
[3,9,20,15,7]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
广度优先搜索,层序遍历,直接写
class Solution {
public int[] levelOrder(TreeNode root) {
//广度优先搜索吗?
if(root == null)
return new int[]{};
List<Integer> list = new ArrayList<>();
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
TreeNode temp = queue.poll();
list.add(temp.val);
if(temp.left != null){
queue.offer(temp.left);
}
if(temp.right != null){
queue.offer(temp.right);
}
}
int[] res = new int[list.size()];
for(int i = 0; i < list.size(); i++){
res[i] = list.get(i);
}
return res;
}
}
剑指 Offer 32 - II. 从上到下打印二叉树 II
题目描述
从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。
例如:
给定二叉树: [3,9,20,null,null,15,7],
3
/ \\
9 20
/ \\
15 7
返回其层次遍历结果:
[
[3],
[9,20],
[15,7]
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-ii-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
一时间忘了怎么标记一层的结束了,想的是在每层结束加个结点来标记,惭愧惭愧
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
//怎么标记一层结束呢,对,size大小
if(root == null)
return new ArrayList<>();
List<List<Integer>> res = new ArrayList<>();
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
int size = queue.size();
List<Integer> list = new ArrayList<>();
while(size > 0){
TreeNode temp = queue.poll();
list.add(temp.val);
if(temp.left != null){
queue.offer(temp.left);
}
if(temp.right != null){
queue.offer(temp.right);
}
size--;
}
res.add(list);
}
return res;
}
}
剑指 Offer 32 - III. 从上到下打印二叉树 III
题目描述
请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。
例如:
给定二叉树: [3,9,20,null,null,15,7],
3
/ \\
9 20
/ \\
15 7
返回其层次遍历结果:
[
[3],
[20,9],
[15,7]
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-iii-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
//判断是奇数层还是偶数层,然后打印?
//而且这次是用栈,后入先出?栈不行,双端队列
//如果当前层是奇数,需要从左到右打印,而下一层需要从右到左,因此该层加入队列中应该是加在队列尾部,
//下一层弹出的时候从尾部弹出
//如果当前层是偶数,从右到左打印了,那么加入子节点应该是从右到左加入,然后下一层反向弹出
//咋写了
List<List<Integer>> res = new ArrayList<>();
if(root == null)
return res;
int index = 1; //层数
Deque<TreeNode> deque = new LinkedList<>();
deque.offer(root);
while(!deque.isEmpty()){
int size = deque.size();
List<Integer> list = new ArrayList<>();
while(size > 0){
if(index % 2 == 1){
TreeNode temp = deque.pollFirst();
list.add(temp.val);
if(temp.left != null){
deque.offerLast(temp.left);
}
if(temp.right != null){
deque.offerLast(temp.right);
}
}
if(index % 2 == 0){
TreeNode temp = deque.pollLast();
list.add(temp.val);
if(temp.right != null){
deque.offerFirst(temp.right);
}
if(temp.left != null){
deque.offerFirst(temp.left);
}
}
size--;
}
index++;
res.add(list);
}
return res;
}
}
懵懵懂懂AC了,感觉这个方法也行,但是总是感觉不够精巧,看了题解,果然,还能更巧:
层序遍历正常,输出按奇偶层数正反向即可
以上是关于LeetCode1482. 制作 m 束花所需的最少天数 / 剑指 Offer 32 . 从上到下打印二叉树I/II/III的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode1482. 制作 m 束花所需的最少天数 / 剑指 Offer 32 . 从上到下打印二叉树I/II/III