二叉树的递归操作(使用深度优先遍历 、 宽度优先遍历、中序遍历)
1.LeetCode199. 二叉树的右视图
通过宽度优先遍历完成,只需找到二叉树的每层中的最右端的结点。
需要创建一个HashMap来维护当前层的最右结点。
HashMap中存的为(当前层数,当前层数的最右端结点的值)。
遍历过程中需要两个队列,一个队列来存当前遍历的结点,一个用来存当前遍历到的结点的高度。
2.LeetCode 113. 路径总和 II
通过深度优先遍历
通过一个栈来实现,当使用深度优先遍历并通过递归过程中,每次在栈中添加一个元素后,在递归过程完成后还需要弹出加入的结点。
3.LeetCode 450. 删除二叉搜索树中的节点
根据搜索二叉树的性质
(1)根节点(root)左子树上的数均是小于根节点的
(2)根节点(root)右子树上的数均是大于根节点的
(3)删除一个节点时(目标节点为aim,以下都用aim表示):
当aim为叶子节点时直接删除该节点;
当aim没有左子树时,将aim的右子树移动到当前aim的位置上;
当aim没有右子树时,将aim的左子树移动到当前aim的位置上;
当要删除节点左右孩子都有时,找到aim右子树上的最小的节点(min),并将当前aim的左子树当做min的左子树。
4.LeetCode 230. 二叉搜索树中第K小的元素
搜索二叉树中的排列就是 左子树 < 根节点 < 右子树,故通过中序遍历即可解决。
中序遍历就是先遍历左子树,根节点,右子树的遍历顺序。
5.LeetCode 516. 最长回文子序列
首先区分概念:(子序列和子串的区别)
子序列代表着中间可以间断不用是一个连续的;
子串就是必须得是在原字符串中连续的一串字符。
解题思路:
创建一个二维的dp数组,那么i代表着begin的位置、j代表着end的位置
状态转移方程:
//当S[i] == S[j]时 那么当前dp[i][j] 就是在以S[i+1..j-1]的字符串的基础上再+2
//成为的S[i..j]的回文字符串
dp[i][j] = dp[i-1][j-1] +2;
//当s[i] != S[j]时 那么就说明S[i] 和 S[j] 不可能同时作为一个回文字符串的首尾
//当前的dp[i][j]就是在S[i+1..j] 或 S[i..j-1]两者上的最大值
dp[i][j] = Math.max(dp[i+1][j],dp[i][j-1]);
6.LeetCode1143. 最长公共子序列
因为是需要进行两个字符串进行匹配的操作所以创建一个二维dp数组,其中dp数组的i,j分别代表着到了text1和text2的哪个位置,dp[i][j]代表着text1[0..i-1]和text[0..j-1]进行匹配得到的最长公共子序列的长度。
状态转移方程:
(1) 当text1[i] == text2[j]时,那么dp[i][j] = dp[i-1][j-1] +1
(就是在说明当前的以i,j结尾的字符串相同,所以要在上一次匹配完得出的最长公共子序列上的长度+1。
(2) 当text1[i] != text2[j]时,那么dp[i][j] = max(dp[i-1][j],dp[i][j-1])
(就是说明当前的以i,j结尾的字符串是不相同,所以就要在dp[i-1][j]或者dp[i][j-1]已经求出的结果中,找出一个最大的)
7. LeetCode 784. 字母大小写全排列
该题使用Character类中几个方法
(1)Character.isLetter(char c) 判断是否是字母
(2)Character.toUpperCase(char c) 转换成大写字母
(3)Character.toLowerCase(char c) 转换成小写字母