打表技巧:数字n是否为连续几个整数的累加和,至少连续2个数字?
提示:有些题目,结果只与一维变量n有关,可以暴力解,打印一批结果,
然后观察结果可能存在的与i之间的特定规律,直接打表,用的时候查表就行,速度o(1)
打表技巧的题目还有:
【1】打表技巧:N个苹果,用6号袋和8号袋装,必须装满每个袋子,最少需要多少个袋子才能装满
【2】打表技巧:有N堆草,牛先吃,羊后吃,轮流吃,谁先吃完谁赢,请问牛和羊谁会赢
本文关于判断n是否为2的幂次方的条件:
【4】怎么判断数字n是否为2的x次方,即2的幂次呢,比如2,4,8,16,32
题目
打表技巧:数字n是否为连续几个整数的累加和,至少连续2个数字
一、审题
示例:
n<2,至少连续俩数字的累加和,false
n=2,1+1,不是连续的,false
n=3,1+2,是连续的,true
n=4,2+2,1+3,1+1+2,1+1+1都不是连续
1+2+3=6
6+4=10
10+5=15
……
或者2+3=5,3+4=7
……
等等,反正由几个连续的数字相加就行
其他不可
暴力推一批n
来了一个数字n,至少尝试连续2个数字的和
(1)显然咱们可以尝试i=1+2+3……这种方案
(2)如果发现能累加和ans=n,就是true
(3)如果发现ans>n就是暂时不能
(4)如果暂时不能,尝试新的开头i=2+3+4+……
不行继续尝试i=3+4+……
(5)直到但是i这个开头,不能超过n/2,为啥呢?
最多连续2个数字的话
如果i=n/2+(n/2+1)+……=n+1+……,肯定大于n了
因此咱们暴力查找,尝试1 2 3 …n/2所有的开头,如果i开头越过n/2了,那直接不可能了,返回false
明白了吧!开头尝试没必要太大
手撕代码
//复习://来了一个数字n,至少尝试连续2个数字的和
public static boolean sumNum(int n){//n>0
if (n < 2) return false;
//(1)显然咱们可以尝试i=1+2+3……这种方案
for (int i = 1; i <= n/2; i++) {//(5)直到但是i这个开头,不能超过n/2,为啥呢?
//最多连续2个数字的话
//如果i=n/2+(n/2+1)+……=n+1+……,肯定大于n了
int ans = i;//i本人算上,加至少加一个数字
for (int j = i + 1; j < n; j++) {
ans += j;//i开头叠加2个以上的连续数字,必须加
if (ans > n) break;//(3)如果发现>n就是暂时不能
if (ans == n) return true;//(2)如果发现能=n,就是true
}
//(4)如果暂时不能,尝试新的开头i=2+3+4+……
//不行继续尝试i=3+4+……
}
//因此咱们暴力查找,尝试1 2 3 …n/2所有的开头,如果i开头越过n/2了,那直接不可能了,返回false
return false;
}
public static void test(){
System.out.println(sumNum(5));
boolean flag = true;
for (int i = 0; i < 100; i++) {
System.out.println(i+":" + isConsecutiveSum2(i));
if (isConsecutiveSum2(i) != sumNum(i)) flag = false;
}
System.out.println();
for (int i = 0; i < 100; i++) {
System.out.println(i+":" + sumNum(i));
}
System.out.println("两个方法是否相同?"+ flag);
}
看看打表结果:
0:false
1:false
2:false
3:true
4:false
5:true
6:true
7:true
8:false
9:true
10:true
11:true
12:true
13:true
14:true
15:true
16:false
17:true
18:true
19:true
20:true
21:true
22:true
23:true
24:true
25:true
26:true
27:true
28:true
29:true
30:true
31:true
32:false
33:true
34:true
35:true
36:true
37:true
38:true
39:true
40:true
41:true
42:true
43:true
44:true
45:true
46:true
47:true
48:true
49:true
50:true
51:true
52:true
53:true
54:true
55:true
56:true
57:true
58:true
59:true
60:true
61:true
62:true
63:true
64:false
65:true
66:true
67:true
68:true
69:true
70:true
71:true
72:true
73:true
74:true
75:true
76:true
77:true
78:true
79:true
80:true
81:true
82:true
83:true
84:true
85:true
86:true
87:true
88:true
89:true
90:true
91:true
92:true
93:true
94:true
95:true
96:true
97:true
98:true
99:true
两个方法是否相同?true
观察暴力解一批n,找规律打表
确实很骚!
你看看,n<2必然false
其余的你看看,但凡n是2 4 8 16 32 64这种是2的幂次时,是false,其余都是true!
牛吧,打表找规律的强大之处就在这了。
怎么判断x是否为2的x次方呢?
easy
看下文的基础知识:
【4】怎么判断数字n是否为2的x次方,即2的幂次呢,比如2,4,8,16,32
当n&(n-1)=0时,说明n是2的幂次方
因此手撕代码就很简单了
//打表
public static boolean fightTableSumNum(int n){
if (n < 2) return false;
return (n & (n - 1)) != 0;//n是2的幂次方返回false,其余返回true
}
public static void test(){
System.out.println(sumNum(5));
boolean flag = true;
boolean flag2 = true;
for (int i = 0; i < 100; i++) {
// System.out.println(i+":" + fightTableSumNum(i));
// System.out.println(i+":" + sumNum(i));
if (isConsecutiveSum2(i) != sumNum(i)) flag = false;
if (isConsecutiveSum2(i) != fightTableSumNum(i)) flag2 = false;
}
// System.out.println();
// for (int i = 0; i < 100; i++) {
// System.out.println(i+":" + sumNum(i));
// }
System.out.println("两个方法是否相同?"+ flag);
System.out.println("两个方法是否相同?"+ flag2);
}
是不是打表之后,超级简单,速度又快?
0:false
1:false
2:false
3:true
4:false
5:true
6:true
7:true
8:false
9:true
10:true
11:true
12:true
13:true
14:true
15:true
16:false
17:true
18:true
19:true
20:true
21:true
22:true
23:true
24:true
25:true
26:true
27:true
28:true
29:true
30:true
31:true
32:false
33:true
34:true
35:true
36:true
37:true
38:true
39:true
40:true
41:true
42:true
43:true
44:true
45:true
46:true
47:true
48:true
49:true
50:true
51:true
52:true
53:true
54:true
55:true
56:true
57:true
58:true
59:true
60:true
61:true
62:true
63:true
64:false
65:true
66:true
67:true
68:true
69:true
70:true
71:true
72:true
73:true
74:true
75:true
76:true
77:true
78:true
79:true
80:true
81:true
82:true
83:true
84:true
85:true
86:true
87:true
88:true
89:true
90:true
91:true
92:true
93:true
94:true
95:true
96:true
97:true
98:true
99:true
两个方法是否相同?true
两个方法是否相同?true
总结
提示:重要经验:
1)n至少连续2个数字累加和,开头不必超过n/2,观察输出实际上和n有一定得关联,就可以总结规律打表了
2)判断n是否为2的n次幂,直接用条件判断:n&(n-1)=0就是,否则不是
3)笔试求AC,可以不考虑空间复杂度,但是面试既要考虑时间复杂度最优,也要考虑空间复杂度最优。