LeetCode 942. 增减字符串匹配 / 1728. 猫和老鼠 II(博弈,不会) / 449. 序列化和反序列化二叉搜索树
Posted Zephyr丶J
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 942. 增减字符串匹配 / 1728. 猫和老鼠 II(博弈,不会) / 449. 序列化和反序列化二叉搜索树相关的知识,希望对你有一定的参考价值。
942. 增减字符串匹配
2022.5.9 每日一题
题目描述
由范围 [0,n] 内所有整数组成的 n + 1 个整数的排列序列可以表示为长度为 n 的字符串 s ,其中:
如果 perm[i] < perm[i + 1] ,那么 s[i] == ‘I’
如果 perm[i] > perm[i + 1] ,那么 s[i] == ‘D’
给定一个字符串 s ,重构排列 perm 并返回它。如果有多个有效排列perm,则返回其中 任何一个 。
示例 1:
输入:s = “IDID”
输出:[0,4,1,3,2]
示例 2:
输入:s = “III”
输出:[0,1,2,3]
示例 3:
输入:s = “DDI”
输出:[3,2,0,1]
提示:
1 <= s.length <= 10^5
s 只包含字符 “I” 或 “D”
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/di-string-match
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
贪心,想到思路就不难了
class Solution
public int[] diStringMatch(String s)
//这个题竟然是个简单题,一时间竟然不知道怎么做
//想到一个思路
//就是每次放只放当前最大和最小数
//例如第一个例子,第一个字母是I,那么说明左边的小,所以放0
//第二个字母是D,那么说明左边的大,放当前最大,也就是4
//第三个字母I,放1;
//这样放置,可以保证每两个元素是肯定满足条件的,
//而因为每次放的要不是最小要不是最大,可以保证不会影响到后面的放置
//那么依次类推,整个都是满足条件的
int n = s.length();
int min = 0;
int max = n;
int[] res = new int[n + 1];
for(int i = 0; i < n; i++)
if(s.charAt(i) == 'I')
res[i] = min;
min++;
else
res[i] = max;
max--;
res[n] = min;
return res;
1728. 猫和老鼠 II
2022.5.10 每日一题
题目描述
一只猫和一只老鼠在玩一个叫做猫和老鼠的游戏。
它们所处的环境设定是一个 rows x cols 的方格 grid ,其中每个格子可能是一堵墙、一块地板、一位玩家(猫或者老鼠)或者食物。
- 玩家由字符 ‘C’ (代表猫)和 ‘M’ (代表老鼠)表示。
- 地板由字符 ‘.’ 表示,玩家可以通过这个格子。
- 墙用字符 ‘#’ 表示,玩家不能通过这个格子。
- 食物用字符 ‘F’ 表示,玩家可以通过这个格子。
- 字符 ‘C’ , ‘M’ 和 ‘F’ 在 grid 中都只会出现一次。
猫和老鼠按照如下规则移动:
- 老鼠 先移动 ,然后两名玩家轮流移动。
- 每一次操作时,猫和老鼠可以跳到上下左右四个方向之一的格子,他们不能跳过墙也不能跳出 grid 。
- catJump 和 mouseJump 是猫和老鼠分别跳一次能到达的最远距离,它们也可以跳小于最大距离的长度。
- 它们可以停留在原地。
- 老鼠可以跳跃过猫的位置。
游戏有 4 种方式会结束:
- 如果猫跟老鼠处在相同的位置,那么猫获胜。
- 如果猫先到达食物,那么猫获胜。
- 如果老鼠先到达食物,那么老鼠获胜。
- 如果老鼠不能在 1000 次操作以内到达食物,那么猫获胜。
给你 rows x cols 的矩阵 grid 和两个整数 catJump 和 mouseJump ,双方都采取最优策略,如果老鼠获胜,那么请你返回 true ,否则返回 false 。
示例 1:
输入:grid = [“####F”,“#C…”,“M…”], catJump = 1, mouseJump = 2
输出:true
解释:猫无法抓到老鼠,也没法比老鼠先到达食物。
示例 2:
输入:grid = [“M.C…F”], catJump = 1, mouseJump = 4
输出:true
示例 3:
输入:grid = [“M.C…F”], catJump = 1, mouseJump = 3
输出:false
示例 4:
输入:grid = [“C…#”,“…#F”,“…#”,“M…”], catJump = 2, mouseJump = 5
输出:false
示例 5:
输入:grid = [“.M…”,“…#…”,“#…#.”,“C#.#.”,“…#F”], catJump = 3, mouseJump = 1
输出:true
提示:
rows == grid.length
cols = grid[i].length
1 <= rows, cols <= 8
grid[i][j] 只包含字符 ‘C’ ,‘M’ ,‘F’ ,‘.’ 和 ‘#’ 。
grid 中只包含一个 ‘C’ ,‘M’ 和 ‘F’ 。
1 <= catJump, mouseJump <= 8
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/cat-and-mouse-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
一眼看过去就不会做的题,不过范围好像不大,能挣扎一下
记得当时猫和老鼠那道题就不怎么会做,这直接来了个更难的…先收藏了
449. 序列化和反序列化二叉搜索树
2022.5.11 每日一题
题目描述
序列化是将数据结构或对象转换为一系列位的过程,以便它可以存储在文件或内存缓冲区中,或通过网络连接链路传输,以便稍后在同一个或另一个计算机环境中重建。
设计一个算法来序列化和反序列化 二叉搜索树 。 对序列化/反序列化算法的工作方式没有限制。 您只需确保二叉搜索树可以序列化为字符串,并且可以将该字符串反序列化为最初的二叉搜索树。
编码的字符串应尽可能紧凑。
示例 1:
输入:root = [2,1,3]
输出:[2,1,3]
示例 2:
输入:root = []
输出:[]
提示:
树中节点数范围是 [0, 10^4]
0 <= Node.val <= 10^4
题目数据 保证 输入的树是一棵二叉搜索树。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/serialize-and-deserialize-bst
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
我的常规想法,也是题解里面的一般做法
/**
* Definition for a binary tree node.
* public class TreeNode
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) val = x;
*
*/
public class Codec
//直接填充空节点的序列化操作也是没问题的
//但是这里给的是二叉搜索树,利用左节点小,右节点大的特点,可以方便的反序列化
//序列化直接前序遍历
//反序列化的时候,先找根。然后根后面接着的就是左边节点,比它大的就是右边结点
//主要是反序列化难写点
// Encodes a tree to a single string.
public String serialize(TreeNode root)
if(root == null)
return "";
StringBuffer sb = new StringBuffer();
preOrder(sb, root);
return sb.substring(0, sb.length() - 1);
public void preOrder(StringBuffer sb, TreeNode root)
if(root == null)
return;
sb.append(root.val + ",");
preOrder(sb, root.left);
preOrder(sb, root.right);
// Decodes your encoded data to tree.
public TreeNode deserialize(String data)
//System.out.println(data);
if("".equals(data))
return null;
String[] ss = data.split(",");
int l = ss.length;
int[] nums = new int[l];
int idx = 0;
for(String s : ss)
nums[idx++] = Integer.parseInt(s);
return build(nums, 0, l - 1);
public TreeNode build(int[] nums, int left, int right)
if(left > right)
return null;
TreeNode root = new TreeNode(nums[left]);
//找第一个比它大的
int i = left + 1;
int j = right;
while(i < j)
int mid = (j - i) / 2 + i;
if(nums[mid] < nums[left])
i = mid + 1;
else
j = mid;
//找到的点需要判断一下
//如果还是小于,那么说明没有大于它的
if(i <= right && nums[i] < nums[left])
root.left = build(nums, left + 1, i);
root.right = null;
return root;
root.left = build(nums, left + 1, i - 1);
root.right = build(nums, i, right);
return root;
// Your Codec object will be instantiated and called as such:
// Codec ser = new Codec();
// Codec deser = new Codec();
// String tree = ser.serialize(root);
// TreeNode ans = deser.deserialize(tree);
// return ans;
然后看了官解的后序遍历,是用栈来代替查找中间数,这个很巧妙
具体来说,就是栈每次弹出的都是根节点,然后利用这个根节点确定下面节点的范围,然后递归
这样不需要查找的话,时间复杂度就能降低
那么想想先序遍历加队列的方式可以吗,应该也行。下面是代码:
/**
* Definition for a binary tree node.
* public class TreeNode
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) val = x;
*
*/
public class Codec
//直接填充空节点的序列化操作也是没问题的
//但是这里给的是二叉搜索树,利用左节点小,右节点大的特点,可以方便的反序列化
//序列化直接前序遍历
//反序列化的时候,先找根。然后根后面接着的就是左边节点,比它大的就是右边结点
//主要是反序列化难写点
// Encodes a tree to a single string.
public String serialize(TreeNode root)
if(root == null)
return "";
StringBuffer sb = new StringBuffer();
preOrder(sb, root);
return sb.substring(0, sb.length() - 1);
public void preOrder(StringBuffer sb, TreeNode root)
if(root == null)
return;
sb.append(root.val + ",");
preOrder(sb, root.left);
preOrder(sb, root.right);
// Decodes your encoded data to tree.
public TreeNode deserialize(String data)
//System.out.println(data);
if("".equals(data))
return null;
String[] ss = data.split(",");
int l = ss.length;
int[] nums = new int[l];
int idx = 0;
Queue<Integer> queue = new LinkedList<>();
for(String s : ss)
queue.offer(Integer.parseInt(s));
return build(queue, -1, 10001);
public TreeNode build(Queue<Integer> queue, int low, int up)
if(queue.isEmpty() || queue.peek() < low || queue.peek() > up)
return null;
int top = queue.poll();
TreeNode root = new TreeNode(top);
root.left = build(queue, low, top);
root.right = build(queue, top, up);
return root;
// Your Codec object will be instantiated and called as such:
// Codec ser = new Codec();
// Codec deser = new Codec();
// String tree = ser.serialize(root);
// TreeNode ans = deser.deserialize(tree);
// return ans;
以上是关于LeetCode 942. 增减字符串匹配 / 1728. 猫和老鼠 II(博弈,不会) / 449. 序列化和反序列化二叉搜索树的主要内容,如果未能解决你的问题,请参考以下文章