这次练习的是LeetCode上标签为树(混了一道标签数学)、列表为热题Top100、难度为中等的几道题目。题解有官方题解也有个人题解,有的地方意思可能表达得不是很清楚也可能存在错误,有问题请提出,感谢❤
1.二叉树的中序遍历
题目描述:
给定一个二叉树,返回它的中序遍历。
示例:
输入: [1,null,2,3]
1
\
2
/
3
输出: [1,3,2]
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-tree-inorder-traversal
题解:
1.说好的“递归是神,迭代是人”呢!?单纯调侃下蛤,这道题递归确实挺简单的,这里的神人可能比较的是代码的简洁度吧。(不过有些题目的迭代是真**的难,想半天看了题解还是不懂😭)这里的进阶就等下回吧😋
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
List<Integer> res = new LinkedList();
public List<Integer> inorderTraversal(TreeNode root) {
// 迭代结束条件
if(root == null) return res;
inorderTraversal(root.left);
res.add(root.val);
inorderTraversal(root.right);
return res;
}
}
2.迭代解法
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new LinkedList<>();
if (root == null) return res;
Stack<TreeNode> treeStack = new Stack<>();
while (!treeStack.isEmpty() || root != null) {
// 有右子节点进来,就将其左子节点入栈
while (root != null) {
treeStack.push(root);
root = root.left;
}
root = treeStack.pop();
res.add(root.val);
root = root.right;
}
return res;
}
}
2.二叉树的层序遍历
题目描述:
给你一个二叉树,请你返回其按层序遍历得到的节点值。 (即逐层地,从左到右访问所有节点)。
示例:
二叉树:[3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回其层次遍历结果:
[
[3],
[9,20],
[15,7]
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-tree-level-order-traversal
题解:
1.树的层序遍历在之前做的标签字符串的题目中有遇到过(好像),所以上来比较顺利的完成了。
总的思路就是:利用队列放各层节点,拿出来的时候再把它的左右节点入队,然后栈不为空疯狂遍历就好啦(在开始出队前,队列的长度就是当前层的节点数了)
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new LinkedList<>();
if (root == null) return res;
Queue<TreeNode> queue = new LinkedList<>();
// 先将头节点入队
queue.add(root);
int length = 0;
while (!queue.isEmpty()) {
List<Integer> numList = new LinkedList<>();
// 此层节点数
length = queue.size();
while (length > 0) {
TreeNode node = queue.poll();
if (node.left != null) queue.add(node.left);
if (node.right != null) queue.add(node.right);
numList.add(node.val);
length--;
}
res.add(numList);
}
return res;
}
}
3.完全平方数
题目描述:
给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, …)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。
示例 1:
输入: n = 12
输出: 3
解释: 12 = 4 + 4 + 4.
示例 2:
输入: n = 13
输出: 2
解释: 13 = 4 + 9.
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/perfect-squares
题解:
1.这道题,想了半天,灵感一现想往动态规划方向想(毕竟这种最值的和大半可以用动态规划)。然后做不出来。看了题解,似懂非懂。然后强行把自己懂了,先凑合放这吧🙃
class Solution {
public int numSquares(int n) {
int[] dp = new int[n+1];
Arrays.fill(dp, Integer.MAX_VALUE);
dp[0] = 0;
// 保存小于i的平方根数
int index = (int) Math.sqrt(n) + 1;
int squareNums[] = new int[index];
for (int i = 1; i < index; ++i) {
squareNums[i] = i * i;
}
for (int j = 1; j <= n; ++j) {
for (int k = 1; k < index; ++k) {
if (j < squareNums[k])
break;
dp[j] = Math.min(dp[j], dp[j - squareNums[k]] + 1);
}
}
return dp[n];
}
}