Algorithm

题目描述

给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。258.各位相加

Example

输入: 38 输出: 2 解释: 各位相加的过程为:3 + 8 = 11, 1 + 1 = 2。 由于 2 是一位数,所以返回 2。

题目解答

解答一(递归)

1
2
3
4
5
6
public class AddDigitsV1 {
    public int addDigits(int num) {
        if(num < 10) return num;
        return addDigits(num % 10 + num / 10);
    }
}

此解法的时间复杂度为O(log(n)),空间复杂度为O(1)

使用递归要满足的条件

  1. 一个任务可以拆分成多个子任务
  2. 每个任务都有相似的处理步骤(流程)
  3. 存在终止条件

解答二(模9法)

1
2
3
4
5
public class addDigitsV2 {
    public int addDigits(int num) {
        return (num - 1) % 9 + 1;
    }
}

查找规律发现可以以%9来得到答案,但是对于整除9的结果就不行了,所以还要采用借1还1的方式来处理。此解的时间复杂度为O(1),空间复杂度为O(1)

Review

Code Smells: If Statements本文是Idea作者代码味道系列的第六篇。讲述作者是怎么处理validateQuery方法中一大堆的if语句的

方法的味道

  1. 11个if语句,有的会检查多个条件
  2. 方法逻辑处理不清晰

重构步骤

  1. 在开始设置保护(终止)条件,如参数验证,把能快速返回的流程放在最前面,这样在后续就不用考虑这些问题了
  2. 对于语议不清的条件语句,可以把它抽取成一个有代表意义名的方法
  3. 删除控制迭代的逻辑,确实,那个if for i++语句看着都难受
  4. 替换多重值检查,即一个变量被多次检查,这就需要深入代码来进行替换,调整if的判断顺序
  5. 将多个if转换成if与else的组合
  6. 简化逻辑,去除多个ifPresent的检查,这次是把ifPresent的语句优先处理

结果

  1. 代码从62行减少到47行
  2. 尽可能的删除不必要的if,使if行为一致
  3. 使用了更多的else语句,时时要想着if与else是天生一对
  4. 快速失败,将提前退出的代表放到方法的顶部
  5. 给每个if条件一个好的名字非常重要,这样可以更好的理解if中的语句在做什么
  6. 人在看代码时更喜欢正向的if处理,所以可能的话,反转消极的if判断(代码更多是给人看的)

Tip

pandoc文档转换利器,可以在markdown,org与pdf,doc之间进行转换,强大到没朋友。如果在org->doc时需要文献的格式,配合上styles更香

Share

今天分享的是Top 11 Open Source Database for Your Next Project,文章分享了11个开源的数据库(不包含Mysql),并且对每个数据库的使用场景进行了说明。