题目:
题目一:求斐波那契数列的第n项。
分析一:
用递归做
代码一:
package offer.xzs.tenth;
public class Fibonacci01 {
public static void main(String[] args) {
int fib = fib(2);
System.out.println(fib);
}
public static int fib(int n) {
if (n == 1 || n == 2) {
return 1;
} else if (n > 2){
return fib(n - 1) + fib(n - 2);
} else {
return 0;
}
}
}
分析二:
非递归,用循环。
代码二:
package offer.xzs.tenth;
public class Fibonacci02 {
public static void main(String[] args) {
int fib = fib(4);
System.out.println(fib);
}
public static int fib(int n) {
if (n <= 0) {
return 0;
}
int fib1 = 0;
int fib2 = 1;
int result = n;
for (int i = 2; i <= n; i++) {
result = fib1 + fib2;
fib1 = fib2;
fib2 = result;
}
return result;
}
}
题目二:一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求这只青蛙跳上一个n级的台阶总共有多少种跳法。
分析一:
这种问题可以用递归来做。
代码一:
package offer.xzs.tenth;
public class Jump01 {
public static void main(String[] args) {
int jump = jump(4);
System.out.println(jump);
}
public static int jump(int n) {
if (n < 1) {
return 0;
} else if (n == 1) {
return 1;
} else if (n == 2) {
return 2;
} else {
return jump(n - 1) + jump(n - 2);
}
}
}
分析二:
用循环。
代码二:
package offer.xzs.tenth;
public class Jump02 {
public static void main(String[] args) {
int jump = jump(4);
System.out.println(jump);
}
public static int jump(int n) {
if (n < 1) {
return 0;
} else if (n == 1) {
return 1;
} else if (n == 2) {
return 2;
}
int result = 0;
int jump1 = 1;
int jump2 = 2;
for (int i = 2; i < n; i++) {
result = jump1 + jump2;
jump1 = jump2;
jump2 = result;
}
return result;
}
}
题目3:一只青蛙一次可以跳上1级台阶、2级台阶......它也可以跳上n级,此时该青蛙跳上n级台阶总共有多少种跳法?
分析一:
递归。
代码一:
package offer.xzs.tenth;
public class IronJump01 {
public static void main(String[] args) {
int jump = jump(4);
System.out.println(jump);
}
public static int jump(int n) {
if (n < 1) {
return 0;
} else if (n == 1) {
return 1;
} else if (n == 2) {
return 2;
} else {
return 2 * jump(n - 1);
}
}
}
分析二:
动态规划。
代码二:
package offer.xzs.tenth;
import java.util.Arrays;
public class IronJump02 {
public static void main(String[] args) {
int jump = jump(4);
System.out.println(jump);
}
public static int jump(int n) {
int[] result = new int[n];
Arrays.fill(result, 1);
for (int i = 1; i < n; i++)
for (int j = 0; j < i; j++)
result[i] += result[j];
return result[n - 1];
}
}
题目四:用2*1的小矩形,横着或者竖着去覆盖更大的矩形。请问8个2*1的小矩形无重叠的覆盖一个2*8的大矩形,总共有多少种方法?
分析一:
递归。
代码一:
package offer.xzs.tenth;
public class Rec01 {
public static void main(String[] args) {
int fib = rec(2);
System.out.println(fib);
}
public static int rec(int n) {
if (n == 1 || n == 2) {
return n;
} else if (n > 2){
return rec(n - 1) + rec(n - 2);
} else {
return 0;
}
}
}
分析二:
循环,代码不实现了。
分析三:
用备忘录方式的递归。
代码三:
package offer.xzs.tenth;
import java.util.HashMap;
import java.util.Map;
public class Rec02 {
public static void main(String[] args) {
Map<Integer, Integer> map = new HashMap<>();
int fib = rec(5, map);
System.out.println(fib);
}
public static int rec(int n) {
Map<Integer, Integer> map = new HashMap<>();
return rec(n, map);
}
public static int rec(int n, Map<Integer, Integer> map) {
if (n == 1 || n == 2) {
return n;
}
if (map.containsKey(n)) {
return map.get(n);
} else {
int value = rec(n - 1, map) + rec(n - 2, map);
map.put(n, value);
return value;
}
}
}