(一)剑指Offer10-I.斐波那契数列
class Solution {
public int fib(int n) {
int[] save = new int[101];
save[0]=0;
save[1]=1;
save[2]=1;
for (int i = 3; i <= n; i++) {
save[i] = (save[i-1]+save[i-2])%1000000007;
}
return save[n];
}
}
(二)剑指Offer10-II.青蛙跳台阶问题
基本思路:
到达最终台阶的方法有两种,即从倒数第一个台阶跳一下、或是从倒数第二个台阶跳两下。于是问题又转化为了跳到倒数第一个台阶有多少中可能、调到倒数第二个台阶有多少种可能。一次地柜,直到问题归到跳到第一个台阶或调到倒数第二个台阶有多少种可能,就终止递归。
class Solution {
public int numWays(int n) {
int a = 1, b = 1, sum;
for(int i = 0; i < n; i++){
sum = (a + b) % 1000000007;
a = b;
b = sum;
}
return a;
}
}
递归的题目往往可以使用动态规划缩短运行时间,下面是动态规划的代码:
public int numWays(int n) {
if(n == 0 || n == 1){
return 1;
}
int[] cases = new int[n+1];
cases[0] = 1;
cases[1] = 1;
for(int i = 2; i <= n; i++){
cases[i] = (cases[i-1] + cases[i-2])% 1000000007;
}
return cases[n] ;
}
(三)剑指 Offer 16. 数值的整数次方
基本思路:
1.如果直接递归求n次方,这道题会超时。
2.可以采用快速幂法,即:
class Solution {
public double myPow(double x, int n) {
//将指数位转化为二进制,每一位都用小一位的值来获得
//首先列举特殊情况:
if(x == 1){
return 1;
}
if(x == -1){
if(n % 2 == 0){
return 1;
}else{
return -1;
}
}
if(x > 0 && n == Integer.MIN_VALUE){
//避免无穷小
return 0;
}
if(n == 0){
return 1;
}
//预先提取符号位,使数值为正
double sign = (n>=0 ? 1:-1);
double res = 1;
int num = (sign >= 0) ? n: -n;
double cur = 1;//存储当前位数所对应的值
while(num > 0){
if(num == Math.abs(n)){
cur *= x;
}else{
cur *= cur;
}
if((num & 0x1) != 0){
res *= cur;
}
num = num >>> 1;
}
return (sign >= 0)? res:(1/res);
// return res;
}
}
(四)剑指 Offer 38. 字符串的排列
基本思路:这一道题牵扯到回溯问题,故选用递归的方法。由于要排列所有的情况,我们可以对于一个字符串,将所有的位都方法第一位排列一次,然后将后面的位都以相同的方法再次排列。
class Solution {
public String[] permutation(String s) {
//每次固定一个字符,然后递归
List<String> list = new ArrayList<>();
if(s.length() == 0){
return list.toArray(new String[0]);
}
char[] words = s.toCharArray();
dfs(words,0,list,"");
return list.toArray(new String[list.size()]);
}
void dfs(char[] words,int start,List<String> list, String head){//上一轮中被固定的元素
//停止条件
if(start == words.length){
list.add(head);
}
HashSet<Character> set = new HashSet<>();
//声明在这里,如果前面已经有过这个组合会直接删除掉。
for(int i = start; i < words.length; i++){//把每一位挪到第一个,然后判断后面的排列组合
if(set.contains(words[i])){
continue;
}
set.add(words[i]);
char tmp = words[start];
words[start] = words[i];
words[i] = tmp;
dfs(words,start+1,list,head+words[start]);
tmp = words[start];
words[start] = words[i];
words[i] = tmp;
}
}
}