关于JAVA的学习出了看视频以外,那就是刷题了,朋友们,你们有没有过这样的感觉,在网上看了视频过后感觉自己什么都听懂了,但就是写题和做项目时无从下手,或者就是因为某个细节一直错一直改,那背后的原因是什么呢?四个字——题刷少了,这里新一建议去
Leetcode
看看,那里的题库资源很丰富,并且在全球都有广泛涉猎。不仅如此,这里还有 课程 + 刷题 + 面经 + 求职 + 讨论区分享解题思路,用过的人都说好
除此之外,我的建议是初学者从简单题
开始练习,因为简单题是一切题的基础,一切的困难题都是从简单题衍生而来的,每天刷那么2~3题,后期再慢慢刷中等题,困难题,经过一段时间后会有很不错的提升
此外,在我们有一定的提升之后,我们便可以去刷剑指offer
了,在这里预祝各位大学生以及初学者都拿到自己满意的offer!
做题链接戳这里:111.二叉树的最小深度
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明:叶子节点是指没有子节点的节点。
● 树中节点数的范围在 [0, 105] 内
● -1000 <= Node.val <= 1000
前序遍历找节点
我们这里递归遍历左右子树,遍历到叶子节点则返回,需要注意的是要找的是最小深度,那么一定是左右树比较的最小深度,除此之外,还需要考虑左右树是否为空的情况,最后返回这两颗子树之间最小值即可。
class Solution {
public int minDepth(TreeNode root) {
if (root == null){
return 0;
}
int leftTree = minDepth(root.left) + 1;
int rightTree = minDepth(root.right) + 1;
if (leftTree == 1){
return rightTree;
}else if (rightTree == 1){
return leftTree;
}else{
return Math.min(leftTree, rightTree);
}
}
}
层序遍历求最小深度
我们之前刷过一道层序遍历的题,可以快速遍历每层节点,我们来思考一个问题,我们按照层序遍历得到的第一个叶子结点是否就是我们所找的最小深度节点呢?当然是,想通了这个就好做了,并且效率提升了不少。
public int minDepth(TreeNode root) {
int cnt = 0;
if (root == null) return cnt;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()){
int size = queue.size();
cnt++;
while (size > 0){
TreeNode cur = queue.poll();
if (cur.left == null && cur.right == null){
return cnt;
}
if (cur.left != null) {
queue.offer(cur.left);
}
if (cur.right != null){
queue.offer(cur.right);
}
size--;
}
}
return cnt;
}
做题链接戳这里,112.路径总和
给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。
叶子节点 是指没有子节点的节点。
● 树中节点的数目在范围 [0, 5000] 内
● -1000 <= Node.val <= 1000
● -1000 <= targetSum <= 1000
我们读完题后,第一反应肯定是遍历二叉树找路径之和是否与目标值相等,那么怎么个遍历法呢,首先,它必须要是一条路径,路径的要素是什么呢?从根节点一路需要到叶子结点,因此最后遍历的值必须要是叶子节点,其次路径总和的计算,我们试想,如果我们记录每条路径的总和,那么问题来了,如果当前路径不对呢?怎么回溯我们所记录的值,这是个大问题,递归里回溯不太现实,实际上我们改变递归函数的参数即可回溯,什么意思呢,我们用“减”的方式,每记录一个节点,就在递归函数中将目标值参数减去相应的值,这样当我们回溯时是不是已经达到了我们想要的效果?最后如果将目标减为了0,即为有效路径,否则无有效路径。
class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if (root == null){
return false;
}
if (root.left == null && root.right == null){
return targetSum - root.val == 0;
}
return hasPathSum(root.left, targetSum - root.val) || hasPathSum(root.right, targetSum - root.val);
}
}
做题链接戳这里:257.二叉树的所有路径
给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。
叶子节点 是指没有子节点的节点。
● 树中节点的数目在范围 [1, 100] 内
● -100 <= Node.val <= 100
我们先看他它提供的函数头,是一个字符串型List,而且它的要求是要返回二叉树的所有路径,我们这里肯定要定义一个list和String,那么这也就意味着我们要重新定义函数了,因为不好直接用题中所给函数来直接操作,首先,我们看它实例,每条路径肯定要进行字符串的拼接,而我们的String拼接十分消耗资源的,所以我们推荐用StringBuilder来进行拼接,原理还是跟上面一样,遇到叶子结点即为一条路径,即将记录的字符串放入list中,那么问题来了,怎么回溯呢,当我们遍历完一条路径后怎么回溯呢,原理还是跟上面一样,改变递归函数的参数即可实现回溯,这里我们新函数的参数为StringBuilder对象,因此每次只需new 一个即可。
class Solution {
public void getList(TreeNode root, StringBuilder sb, List<String> ret){
if (root == null){
return;
}
sb.append(root.val);
if (root.left == null && root.right == null){
ret.add(sb.toString());
}else{
sb.append("->");
getList(root.left, new StringBuilder(sb), ret);
getList(root.right,new StringBuilder(sb), ret);
}
}
public List<String> binaryTreePaths(TreeNode root) {
List<String> list = new ArrayList<>();
if (root == null){
return list;
}
StringBuilder sb = new StringBuilder();
getList(root,sb, list);
return list;
}
}