1.高频面试试题
实现方法:
1、递归
2、循环迭代
1.递归
public class TestStep{
@Test
public void test(){
long start = System.currentTimeMillis();
System.out.println(f(100));//165580141
long end = System.currentTimeMillis();
System.out.println(end-start);//586ms
}
//实现f(n):求n步台阶,一共有几种走法
public int f(int n){
if(n<1){
throw new IllegalArgumentException(n + "不能小于1");
}
if(n==1 || n==2){
return n;
}
return f(n-2) + f(n-1);
}
}
递归运算:运算效率不是很高,但是代码便捷上比较简单
2.循环迭代
public class TestStep2 {
@Test
public void test(){
long start = System.currentTimeMillis();
System.out.println(loop(100));//165580141
long end = System.currentTimeMillis();
System.out.println(end-start);//<1ms
}
public int loop(int n){
if(n<1){
throw new IllegalArgumentException(n + "不能小于1");
}
if(n==1 || n==2){
return n;
}
int one = 2;//初始化为走到第二级台阶的走法
int two = 1;//初始化为走到第一级台阶的走法
int sum = 0;
for(int i=3; i<=n; i++){
//最后跨2步 + 最后跨1步的走法
sum = two + one;
two = one;
one = sum;
}
return sum;
}
}
循环迭代:代码运行效率高,但是可读性差
3. ForkJoinPool解决递归算法
/**
* 菲尼伯兹函数ForkJoin实现
*
* @author haozy
* @create 2020-07-06 15:35
**/
public class ForkJoinTest {
public static void main(String[] args) {
ForkJoinPool pool = new ForkJoinPool();
FeiTask feiTask = new FeiTask(30l);
Instant start = Instant.now();
Long sum = pool.invoke(feiTask);
System.out.println(sum);
Instant end = Instant.now();
System.out.println("耗费时间为:" + Duration.between(start, end).toMillis());//166-1996-10590
}
}
class FeiTask extends RecursiveTask<Long>{
private long fn ;
public FeiTask(long fn) {
this.fn = fn;
}
@Override
protected Long compute() {
if(fn<=0){
throw new RuntimeException("参数小于0");
}
if(fn == 1L ||fn == 2L){
return fn;
}
FeiTask first = new FeiTask(fn-1);
first.fork();
FeiTask second = new FeiTask(fn-2);
second.fork();
return first.join() + second.join();
}
}
比递归算法还要耗时但是写法更加简单