LeetCode 96~100
2021/11/15 23:14:33
本文主要是介绍LeetCode 96~100,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
前言
本文隶属于专栏《LeetCode 刷题汇总》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢!
本专栏目录结构请见LeetCode 刷题汇总
正文
幕布
幕布链接
96. 不同的二叉搜索树
题解
官方题解
动态规划
class Solution { public int numTrees(int n) { int[] G = new int[n + 1]; G[0] = G[1] = 1; for (int i = 2; i <= n; i++) { for (int j = 1; j <= i; j++) { G[i] += G[j - 1] * G[i - j]; } } return G[n]; } }
数学,卡特兰数
class Solution { public int numTrees(int n) { // 提示:我们在这里需要用 long 类型防止计算过程中的溢出 long C = 1; for (int i = 0; i < n; ++i) { C = C * 2 * (2 * i + 1) / (i + 2); } return (int) C; } }
97. 交错字符串
题解
类似路径问题,找准状态方程快速求解
路径问题
class Solution { public boolean isInterleave(String s1, String s2, String s3) { int m = s1.length(), n = s2.length(); if (s3.length() != m + n) return false; // 动态规划,dp[i,j]表示s1前i字符能与s2前j字符组成s3前i+j个字符; boolean[][] dp = new boolean[m+1][n+1]; dp[0][0] = true; for (int i = 1; i <= m && s1.charAt(i-1) == s3.charAt(i-1); i++) dp[i][0] = true; // 不相符直接终止 for (int j = 1; j <= n && s2.charAt(j-1) == s3.charAt(j-1); j++) dp[0][j] = true; // 不相符直接终止 for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { dp[i][j] = (dp[i - 1][j] && s3.charAt(i + j - 1) == s1.charAt(i - 1)) || (dp[i][j - 1] && s3.charAt(i + j - 1) == s2.charAt(j - 1)); } } return dp[m][n]; } }
98. 验证二叉搜索树
题解
官方题解
递归 + long pre
class Solution { long pre = Long.MIN_VALUE; // 记录上一个节点的值,初始值为Long的最小值 public boolean isValidBST(TreeNode root) { return inorder(root); } // 中序遍历 private boolean inorder(TreeNode node) { if(node == null) return true; boolean l = inorder(node.left); if(node.val <= pre) return false; pre = node.val; return l && inorder(node.right); } }
栈迭代+long pre
class Solution { private boolean flag = true; private long pre = Long.MIN_VALUE; public boolean isValidBST(TreeNode root) { if(root == null){ return true; } helper(root); return flag; } private void helper(TreeNode root){ Stack<TreeNode> stack = new Stack<>(); while(root != null || !stack.isEmpty()){ while(root != null){ stack.push(root); root = root.left; } root = stack.pop(); if(root.val <= pre){ flag = false; break; } pre = root.val; root = root.right; } } }
99. 恢复二叉搜索树
题解
官方题解
显式中序遍历+数组+递归
class Solution { public void recoverTree(TreeNode root) { List<Integer> nums = new ArrayList<Integer>(); inorder(root, nums); int[] swapped = findTwoSwapped(nums); recover(root, 2, swapped[0], swapped[1]); } public void inorder(TreeNode root, List<Integer> nums) { if (root == null) { return; } inorder(root.left, nums); nums.add(root.val); inorder(root.right, nums); } public int[] findTwoSwapped(List<Integer> nums) { int n = nums.size(); int index1 = -1, index2 = -1; for (int i = 0; i < n - 1; ++i) { if (nums.get(i + 1) < nums.get(i)) { index2 = i + 1; if (index1 == -1) { index1 = i; } else { break; } } } int x = nums.get(index1), y = nums.get(index2); return new int[]{x, y}; } public void recover(TreeNode root, int count, int x, int y) { if (root != null) { if (root.val == x || root.val == y) { root.val = root.val == x ? y : x; if (--count == 0) { return; } } recover(root.left, count, x, y); recover(root.right, count, x, y); } } }
隐式中序遍历+栈,x/y/prev
class Solution { public void recoverTree(TreeNode root) { Deque<TreeNode> stack = new ArrayDeque<>(); TreeNode x = null, y = null, prev = null; while (!stack.isEmpty() || root != null) { while (root != null) { stack.push(root); root = root.left; } root = stack.pop(); if (prev != null && root.val < prev.val) { y = root; if (x == null) { x = prev; } else { break; } } prev = root; root = root.right; } swap(x, y); } public void swap(TreeNode x, TreeNode y) { int tmp = x.val; x.val = y.val; y.val = tmp; } }
Morris 遍历算法
class Solution { public void recoverTree(TreeNode root) { TreeNode x = null, y = null, pred = null, predecessor = null; while (root != null) { if (root.left != null) { // predecessor 节点就是当前 root 节点向左走一步,然后一直向右走至无法走为止 predecessor = root.left; while (predecessor.right != null && predecessor.right != root) { predecessor = predecessor.right; } // 让 predecessor 的右指针指向 root,继续遍历左子树 if (predecessor.right == null) { predecessor.right = root; root = root.left; } // 说明左子树已经访问完了,我们需要断开链接 else { if (pred != null && root.val < pred.val) { y = root; if (x == null) { x = pred; } } pred = root; predecessor.right = null; root = root.right; } } // 如果没有左孩子,则直接访问右孩子 else { if (pred != null && root.val < pred.val) { y = root; if (x == null) { x = pred; } } pred = root; root = root.right; } } swap(x, y); } public void swap(TreeNode x, TreeNode y) { int tmp = x.val; x.val = y.val; y.val = tmp; } }
100. 相同的树
题解
官方题解
递归
class Solution { public boolean isSameTree(TreeNode p, TreeNode q) { if (p == null && q == null) { return true; } else if (p == null || q == null) { return false; } else if (p.val != q.val) { return false; } else { return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); } } }
这篇关于LeetCode 96~100的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享