目录
1、LeetCode 257.二叉树的所有路径
题目
给定一个二叉树,返回所有从根节点到叶子节点的路径。
说明: 叶子节点是指没有子节点的节点。
思路与算法
最直观的方法是使用深度优先搜索。在深度优先搜索遍历二叉树时,我们需要考虑当前的节点以及它的孩子节点。
如果当前节点不是叶子节点,则在当前的路径末尾添加该节点,并继续递归遍历该节点的每一个孩子节点。
如果当前节点是叶子节点,则在当前路径末尾添加该节点后我们就得到了一条从根节点到叶子节点的路径,将该路径加入到答案即可。
如此,当遍历完整棵二叉树以后我们就得到了所有从根节点到叶子节点的路径。
小编菜解
public List<String> binaryTreePaths(TreeNode root) {
List<String> list = new ArrayList<>();
constructPaths(root, "", list);
return list;
}
private void constructPaths(TreeNode root, String path, List<String> pathList){
if (root != null){
StringBuilder builder = new StringBuilder(path);
builder.append(Integer.toString(root.val));
if (root.left == null && root.right == null){//当前节点是叶子节点
pathList.add(builder.toString()); //把路径加入到答案中
}else {
builder.append("->");//当前结点不是叶子结点,继续递归遍历
constructPaths(root.left, builder.toString(),pathList);
constructPaths(root.right, builder.toString(),pathList);
}
}
}
2、LeetCode 258.各位相加
题目
给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。
小编解题思路
各位相加,使用递归,出口是结果的长度等于1
小编菜解
public static int addDigits(int num) {
recursion(num);
return re;
}
static int re = 0;
private static void recursion(int num){
String str = String.valueOf(num);
int ret = 0;
for (int i = 0; i < str.length(); i++) {
ret += Integer.parseInt(String.valueOf(str.charAt(i)));
}
if(String.valueOf(ret).length() > 1){
recursion(ret);
}else{
re = ret;
}
}
注意char转int是有更好的方法的。
Character.getNumericValue(str.charAt(i));
思路与算法
时间复杂度为 O(1)O(1)的解法:
除个位外,每一位上的值都是通过 (9+1) 进位的过程得到的,想一下 拨算盘进位
把整数 n 看成 n 样物品,原本是以 10 个 1 份打包的,现在从这些 10 个 1 份打包好的里面,拿出 1 个,让它们以 9 个为 1 份打包。
这样就出现了两部分的东西:
原本 10 个现在 9 个 1 份的,打包好的物品,这些,我们不用管
零散的物品,它们还可以分成:
从原来打包的里面拿出来的物品,它们的总和 =》 原来打包好的份数 =》 10进制进位的次数 =》 10 进制下,除个位外其他位上的值的总和
以 10 个 1 份打包时,打不进去的零散物品 =》 10 进制个位上的值
如上零散物品的总数,就是第一次处理 num 后得到的累加值
如果这个累加值 >9,那么如题就还需要将各个位上的值再相加,直到结果为个位数为止。也就意味着还需要来一遍如上的过程。
那么按照如上的思路,似乎可以通过 n % 9 得到最后的值
但是有1个关键的问题,如果 num 是 9 的倍数,那么就不适用上述逻辑。原本我是想得到 n 被打包成 10 个 1 份的份数+打不进 10 个 1 份的散落个数的和。通过与 9 取模,去获得那个不能整除的 1,作为计算份数的方式,但是如果可以被 9 整除,我就无法得到那个 1,也得不到个位上的数。
所以需要做一下特殊处理,(num - 1) % 9 + 1
可以这么做的原因:原本可以被完美分成 9 个为一份的 n 样物品,我故意去掉一个,那么就又可以回到上述逻辑中去得到我要的n 被打包成 10 个一份的份数+打不进 10 个一份的散落个数的和。而这个减去的 1 就相当于从,在 10 个 1 份打包的时候散落的个数中借走的,本来就不影响原来 10 个 1 份打包的份数,先拿走再放回来,都只影响散落的个数,所以没有关系。
大佬指点江山
public int addDigits(int num) {
return (num - 1) % 9 + 1;
}
3、LeetCode 263.丑数
题目
给你一个整数 n ,请你判断 n 是否为 丑数 。如果是,返回 true ;否则,返回 false 。
丑数 就是只包含质因数 2、3 和/或 5 的正整数。
小编菜解
public static boolean isUgly(int n) {
if (n<=0){
return false;
}
int[] nums = {2,3,5};
for (int x : nums){
if (n%x == 0){
n /= x;
}
}
return n == 1;
}