641.设计循环双端队列、768.最多能完成排序的块 II(未完成)、1282.用户分组、1302.层数最深叶子节点的和、1422.分割字符串的最大得分

This commit is contained in:
游由 2022-08-17 16:50:11 +08:00
parent 27ccef7e85
commit 0f5d520917
7 changed files with 414 additions and 0 deletions

View File

@ -3,6 +3,7 @@ mod q0225;
mod q0232;
mod q0297;
mod q0622;
mod q0641;
mod q0705;
mod q0706;
mod q0707;

146
rust/src/design/q0641.rs Normal file
View File

@ -0,0 +1,146 @@
use crate::Solution;
/// [641.设计循环双端队列](https://leetcode.cn/problems/design-circular-deque/)
///
/// 2022-08-15 09:41:14
///
/// 设计实现双端队列。
///
/// + 实现 `MyCircularDeque` 类:
/// * `MyCircularDeque(int k)` :构造函数,双端队列最大为 `k` 。
/// * `boolean insertFront()`:将一个元素添加到双端队列头部。 如果操作成功返回 `true` ,否则返回 `false` 。
/// * `boolean insertLast()` :将一个元素添加到双端队列尾部。如果操作成功返回 `true` ,否则返回 `false` 。
/// * `boolean deleteFront()` :从双端队列头部删除一个元素。 如果操作成功返回 `true` ,否则返回 `false` 。
/// * `boolean deleteLast()` :从双端队列尾部删除一个元素。如果操作成功返回 `true` ,否则返回 `false` 。
/// * `int getFront()` ):从双端队列头部获得一个元素。如果双端队列为空,返回 `-1` 。
/// * `int getRear()` :获得双端队列的最后一个元素。 如果双端队列为空,返回 `-1` 。
/// * `boolean isEmpty()` :若双端队列为空,则返回 `true` ,否则返回 `false` 。
/// * `boolean isFull()` :若双端队列满了,则返回 `true` ,否则返回 `false` 。
/// + **示例 1**
///
/// + **输入**
/// + \["MyCircularDeque", "insertLast", "insertLast", "insertFront", "insertFront", "getRear", "isFull", "deleteLast", "insertFront", "getFront"\]
/// + \[\[3\], \[1\], \[2\], \[3\], \[4\], \[\], \[\], \[\], \[4\], \[\]\]
/// + **输出**
/// + \[null, true, true, true, false, 2, true, true, true, 4\]
/// + **解释**
/// ```java
/// MyCircularDeque circularDeque = new MycircularDeque(3); // 设置容量大小为3
/// circularDeque.insertLast(1); // 返回 true
/// circularDeque.insertLast(2); // 返回 true
/// circularDeque.insertFront(3); // 返回 true
/// circularDeque.insertFront(4); // 已经满了,返回 false
/// circularDeque.getRear(); // 返回 2
/// circularDeque.isFull(); // 返回 true
/// circularDeque.deleteLast(); // 返回 true
/// circularDeque.insertFront(4); // 返回 true
/// circularDeque.getFront(); // 返回 4
/// ```
/// + **提示:**
/// * `1 <= k <= 1000`
/// * `0 <= value <= 1000`
/// * `insertFront`, `insertLast`, `deleteFront`, `deleteLast`, `getFront`, `getRear`, `isEmpty`, `isFull` 调用次数不大于 `2000` 次
/// + Related Topics
/// * 设计
/// * 队列
/// * 数组
/// * 链表
struct MyCircularDeque {
s: usize,
e: usize,
c: usize,
q: Vec<i32>,
}
impl MyCircularDeque {
fn new(k: i32) -> Self {
MyCircularDeque {
s: 0,
e: 0,
c: (k + 1) as usize,
q: vec![-1; (k + 1) as usize],
}
}
fn insert_front(&mut self, value: i32) -> bool {
if self.is_full() {
return false;
}
self.s = match self.s {
0 => self.c - 1,
_ => (self.s - 1) % self.c
};
self.q[self.s] = value;
true
}
fn insert_last(&mut self, value: i32) -> bool {
if self.is_full() {
return false;
}
self.q[self.e] = value;
self.e = (self.e + 1) % self.c;
true
}
fn delete_front(&mut self) -> bool {
if self.is_empty() {
return false;
}
self.s = (self.s + 1) % self.c;
true
}
fn delete_last(&mut self) -> bool {
if self.is_empty() {
return false;
}
self.e = match self.e {
0 => self.c - 1,
_ => (self.e - 1) % self.c
};
true
}
fn get_front(&self) -> i32 {
match self.is_empty() {
true => -1,
_ => self.q[self.s]
}
}
fn get_rear(&self) -> i32 {
match self.is_empty() {
true => -1,
_ => self.q[(self.e + self.c - 1) % self.c]
}
}
fn is_empty(&self) -> bool {
self.s == self.e
}
fn is_full(&self) -> bool {
((self.e + 1) % self.c) == self.s
}
}
#[cfg(test)]
mod test {
use crate::Solution;
use crate::design::q0641::MyCircularDeque;
#[test]
fn test_q0641() {
let mut obj = MyCircularDeque::new(3);
assert_eq!(obj.insert_last(1), true);
assert_eq!(obj.insert_last(2), true);
assert_eq!(obj.insert_front(3), true);
assert_eq!(obj.insert_front(4), false);
assert_eq!(obj.get_rear(), 2);
assert_eq!(obj.is_full(), true);
assert_eq!(obj.delete_last(), true);
assert_eq!(obj.insert_front(4), true);
assert_eq!(obj.get_front(), 4);
}
}

View File

@ -152,6 +152,7 @@ mod q0733;
mod q0740;
mod q0746;
mod q0761;
mod q0768;
mod q0778;
mod q0781;
mod q0783;
@ -189,8 +190,10 @@ mod q1203;
mod q1218;
mod q1269;
mod q1281;
mod q1282;
mod q1288;
mod q1295;
mod q1302;
mod q1310;
mod q1342;
mod q1374;
@ -199,6 +202,7 @@ mod q1404;
mod q1408;
mod q1413;
mod q1417;
mod q1422;
mod q1447;
mod q1473;
mod q1480;

View File

@ -0,0 +1,48 @@
use crate::Solution;
impl Solution {
/// [768.最多能完成排序的块 II](https://leetcode.cn/problems/max-chunks-to-make-sorted-ii/)
///
/// 2022-08-17 16:39:36
///
/// _这个问题和“最多能完成排序的块”相似但给定数组中的元素可以重复输入数组最大长度为`2000`,其中的元素最大为`10**8`。_
///
/// `arr`是一个可能包含**重复元素**的整数数组,我们将这个数组分割成几个“块”,并将这些块分别进行排序。之后再连接起来,使得连接的结果和按升序排序后的原数组相同。
///
/// 我们最多能将数组分成多少块?
///
/// + **示例 1:**
/// + **输入:** arr = \[5,4,3,2,1\]
/// + **输出:** 1
/// + **解释:**
/// + 将数组分成2块或者更多块都无法得到所需的结果。
/// + 例如,分成 \[5, 4\], \[3, 2, 1\] 的结果是 \[4, 5, 1, 2, 3\],这不是有序的数组。
/// + **示例 2:**
/// + **输入:** arr = \[2,1,3,4,4\]
/// + **输出:** 4
/// + **解释:**
/// + 我们可以把它分成两块,例如 \[2, 1\], \[3, 4, 4\]。
/// + 然而,分成 \[2, 1\], \[3\], \[4\], \[4\] 可以得到最多的块数。
/// + **注意:**
/// * `arr`的长度在`[1, 2000]`之间。
/// * `arr[i]`的大小在`[0, 10**8]`之间。
/// + Related Topics
/// * 栈
/// * 贪心
/// * 数组
/// * 排序
/// * 单调栈
pub fn max_chunks_to_sorted(arr: Vec<i32>) -> i32 {
unimplemented!()
}
}
#[cfg(test)]
mod test {
use crate::Solution;
#[test]
fn test_q0768() {
unimplemented!()
}
}

View File

@ -0,0 +1,49 @@
use crate::Solution;
impl Solution {
/// [1282.用户分组](https://leetcode.cn/problems/group-the-people-given-the-group-size-they-belong-to/)
///
/// 2022-08-12 08:14:37
///
/// 有 `n` 个人被分成数量未知的组。每个人都被标记为一个从 `0` 到 `n - 1` 的**唯一ID** 。
///
/// 给定一个整数数组 `groupSizes` ,其中 `groupSizes[i]` 是第 `i` 个人所在的组的大小。例如,如果 `groupSizes[1] = 3` ,则第 `1` 个人必须位于大小为 `3` 的组中。
///
/// 返回一个组列表,使每个人 `i` 都在一个大小为 _ `groupSizes[i]` _的组中。
///
/// 每个人应该 **恰好只 **出现在 **一个组 **中,并且每个人必须在一个组中。如果有多个答案,返回其中 **任何 **一个。可以 **保证 **给定输入 **至少有一个 **有效的解。
///
/// + **示例 1**
/// + **输入:** groupSizes = \[3,3,3,3,3,1,3\]
/// + **输出:** \[\[5\],\[0,1,2\],\[3,4,6\]\]
/// + **解释:**
/// + 第一组是 \[5\],大小为 1groupSizes\[5\] = 1。
/// + 第二组是 \[0,1,2\],大小为 3groupSizes\[0\] = groupSizes\[1\] = groupSizes\[2\] = 3。
/// + 第三组是 \[3,4,6\],大小为 3groupSizes\[3\] = groupSizes\[4\] = groupSizes\[6\] = 3。
/// + 其他可能的解决方案有 \[\[2,1,6\],\[5\],\[0,4,3\]\] 和 \[\[5\],\[0,6,2\],\[4,3,1\]\]。
/// + **示例 2**
/// + **输入:** groupSizes = \[2,1,3,3,3,2\]
/// + **输出:** \[\[1\],\[0,5\],\[2,3,4\]\]
/// + **提示:**
/// * `groupSizes.length == n`
/// * `1 <= n <= 500`
/// * `1 <= groupSizes[i] <= n`
/// + Related Topics
/// * 数组
/// * 哈希表
pub fn group_the_people(group_sizes: Vec<i32>) -> Vec<Vec<i32>> {
let mut m = std::collections::HashMap::<i32, Vec<i32>>::new();
group_sizes.into_iter().enumerate().for_each(|(idx, val)| m.entry(val).or_default().push(idx as i32));
m.into_iter().map(|(k, v)| v.chunks(k as usize).into_iter().map(|i| i.to_vec()).collect::<Vec<Vec<i32>>>()).flatten().collect()
}
}
#[cfg(test)]
mod test {
use crate::Solution;
#[test]
fn test_q1282() {
assert_eq!(Solution::group_the_people(vec![3, 3, 3, 3, 3, 1, 3]), vec![vec![0, 1, 2], vec![3, 4, 6], vec![5]]);
}
}

View File

@ -0,0 +1,97 @@
use crate::Solution;
use crate::structure::TreeNode;
use std::rc::Rc;
use std::cell::RefCell;
impl Solution {
/// [1302.层数最深叶子节点的和](https://leetcode.cn/problems/deepest-leaves-sum/)
///
/// 2022-08-17 09:11:35
///
/// 给你一棵二叉树的根节点 `root` ,请你返回 **层数最深的叶子节点的和** 。
///
/// + **示例 1**
/// + **![](https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2019/12/28/1483_ex1.png)**
/// + **输入:**root = \[1,2,3,4,5,null,6,7,null,null,null,null,8\]
/// + **输出:**15
/// + **示例 2**
/// + **输入:**root = \[6,7,8,2,7,1,3,9,null,1,4,null,null,null,5\]
/// + **输出:**19
/// + **提示:**
/// * 树中节点数目在范围 `[1, 104]` 之间。
/// * `1 <= Node.val <= 100`
/// + Related Topics
/// * 树
/// * 深度优先搜索
/// * 广度优先搜索
/// * 二叉树
pub fn deepest_leaves_sum(root: Option<Rc<RefCell<TreeNode>>>) -> i32 {
let mut v = vec![];
match root {
Some(n) => v.push(n),
_ => return 0
}
let mut s = 0;
while !v.is_empty() {
s = 0;
let mut t = vec![];
for n in v {
s += n.borrow().val;
if let Some(l) = n.borrow_mut().left.take() {
t.push(l);
}
if let Some(r) = n.borrow_mut().right.take() {
t.push(r);
}
}
v = t;
}
s
}
}
#[cfg(test)]
mod test {
use std::cell::RefCell;
use std::rc::Rc;
use crate::Solution;
use crate::structure::TreeNode;
#[test]
fn test_q1302() {
let tree = Some(Rc::new(RefCell::new(TreeNode {
val: 1,
left: Some(Rc::new(RefCell::new(TreeNode {
val: 2,
left: Some(Rc::new(RefCell::new(TreeNode {
val: 4,
left: None,
right: Some(Rc::new(RefCell::new(TreeNode {
val: 7,
left: None,
right: None,
}))),
}))),
right: Some(Rc::new(RefCell::new(TreeNode {
val: 5,
left: None,
right: None,
}))),
}))),
right: Some(Rc::new(RefCell::new(TreeNode {
val: 3,
left: None,
right: Some(Rc::new(RefCell::new(TreeNode {
val: 6,
left: None,
right: Some(Rc::new(RefCell::new(TreeNode {
val: 8,
left: None,
right: None,
}))),
}))),
}))),
})));
assert_eq!(Solution::deepest_leaves_sum(tree), 15);
}
}

View File

@ -0,0 +1,69 @@
use crate::Solution;
impl Solution {
/// [1422.分割字符串的最大得分](https://leetcode.cn/problems/maximum-score-after-splitting-a-string/)
///
/// 2022-08-17 14:24:53
///
/// 给你一个由若干 0 和 1 组成的字符串 `s` ,请你计算并返回将该字符串分割成两个 **非空** 子字符串(即 **左** 子字符串和 **右** 子字符串)所能获得的最大得分。
///
/// 「分割字符串的得分」为 **左** 子字符串中 **0** 的数量加上 **右** 子字符串中 **1** 的数量。
///
/// + **示例 1**
/// + **输入:** s = "011101"
/// + **输出:** 5
/// + **解释:**
/// + 将字符串 s 划分为两个非空子字符串的可行方案有:
/// + 左子字符串 = "0" 且 右子字符串 = "11101",得分 = 1 + 4 = 5
/// + 左子字符串 = "01" 且 右子字符串 = "1101",得分 = 1 + 3 = 4
/// + 左子字符串 = "011" 且 右子字符串 = "101",得分 = 1 + 2 = 3
/// + 左子字符串 = "0111" 且 右子字符串 = "01",得分 = 1 + 1 = 2
/// + 左子字符串 = "01110" 且 右子字符串 = "1",得分 = 2 + 1 = 3
/// + **示例 2**
/// + **输入:** s = "00111"
/// + **输出:** 5
/// + **解释:** 当 左子字符串 = "00" 且 右子字符串 = "111" 时,我们得到最大得分 = 2 + 3 = 5
/// + **示例 3**
/// + **输入:** s = "1111"
/// + **输出:** 3
/// + **提示:**
/// * `2 <= s.length <= 500`
/// * 字符串 `s` 仅由字符 `'0'` 和 `'1'` 组成。
/// + Related Topics
/// * 字符串
pub fn max_score(s: String) -> i32 {
/*let bytes = s.into_bytes();
let s1 = bytes.iter().filter(|&&b| b == b'0').count();
let s2 = bytes.len() - s1;
if s1 == 0 || s2 == 0 {
return (bytes.len() - 1) as i32;
}
let (mut t, mut count) = (0, 0);
for i in 1..bytes.len() {
if bytes[i - 1] == b'0' {
count += 1;
}
let curr = count + s2 - (i - count);
if t < curr {
t = curr;
}
}
t as i32*/
match (1..s.len()).into_iter().fold((i32::MIN, 0i32, s.into_bytes()), |(m, o, b), i| (m.max(i as i32 - (o + (b[i - 1] - b'0') as i32) * 2), o + (b[i - 1] - b'0') as i32, b)) {
(m, o, b) => m + o + (b[b.len() - 1] - b'0') as i32
}
//unimplemented!()
}
}
#[cfg(test)]
mod test {
use crate::Solution;
#[test]
fn test_q1422() {
assert_eq!(Solution::max_score("011101".to_owned()), 5);
assert_eq!(Solution::max_score("00111".to_owned()), 5);
assert_eq!(Solution::max_score("1111".to_owned()), 3);
}
}