最开始,我是直接暴力求解丑数的。抛开时间上的限制,我没想到会出现这么多意料之外的错误。在这个过程中,暴露了一些问题。这篇博客记录一下。
问题描述
给你一个整数 n ,请你判断 n 是否为 丑数 。如果是,返回 true ;否则,返回 false 。
丑数 就是只包含质因数 2、3 、 5 的正整数。
简单分析
根据丑数的定义,一个数如果是丑数,那么它将满足两个条件:
- 该数是一个正整数
- 该数的因子只会是 2、3、5,没有其他的因数存在。
- 1 是丑数
错误一
相比于后面两个问题,这个问题让我学到的东西最多。先把代码放下来:
class Solution {
public boolean isUgly(int n) {
if(n == 1)
return true;
for(int i = 2; i < n; ++i){
if(n % i == 0){
if(i != 2 || i != 3 || i != 5)
return false;
}
}
return true;
}
}
错误是在输入 6 的时候出错的。我不太明白问题出在哪?所以我便debug了一下。发现在 第二层 if
语句中便出现了错误。
在因子为2 的时候,程序竟然会执行到 if
里面?按照我的逻辑
在该因子不是2 或者 不是3 或者 不是5的时候才会返回 false。
但是,在因子是2的情况下,竟然还会输出false。慢慢地,我发现,这程序在运算 i != 2
之后还会运行 i != 3
…我当时脑子一下子就瓦特了。不对呀,||会短路呀,i!=2
是false, 为什么还会执行 i!=3
。于是,我便重新搜索了一下 ||
。
「短路」运算符
&&、|| 都是一个短路 的逻辑运算符。如果该表达式可以通过一侧的运算结果确定「最终的结果」的情况下,那么另一侧的表达式将不会运行。
对于 || 来说, 左侧的表达式为 false
,并不能说明最终的结果究竟是 true
还是 false
。所以,程序最终还会执行 i !=3
。
a | b | a||b |
---|---|---|
true | false | true |
true | true | true |
false | true | true |
false | false | false |
总结一下:对于 || 来说,只有当左侧为true时,才会短路
我把它和 &&
搞混了:
a | b | a&&b |
---|---|---|
true | true | true |
true | false | false |
false | false | false |
false | true | false |
总结一下:对于&&来说,只有当左侧为false时,才会短路。
正是因为当 i=2
时,i!=2
是 false
,所以才会执行 i!