递归算法
绝大多数编程语言支持函数的自调用,在这些语言中函数可以通过调用自身来进行递归。计算理论可以证明递归的作用可以完全取代循环,因此在很多函数编程语言(如Scheme)中习惯用递归来实现循环。
1.求1~50的和
static int countsum(int i) {
if(i==1) {
return 1;
}else {
return i+countsum(i-1);
}
}
public static void main(String args[]){
int sum=0;
sum = countsum(50);
System.out.println("1+2+3+4+...+50="+sum);
}
2.猴子偷桃问题
有一只猴子,第一天偷了若干桃子,并吃了一半多一个;第二天又吃了昨天剩下的一半多一个;第三天又吃昨天剩下的一半多一个;到十天,还想再吃时,就只剩下一个桃子了。
问:桃子总共有多少?
static int countsum(int day){
if(day==10){
return 1;
}else {
return (countsum(day+1)+1)*2;
}
}
public static void main(String args[]){
System.out.println("猴子共偷了"+countsum(1)+"个桃");
}
3.斐波那契
斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。
设F(0)=0; F(1)=1;
F(n)=F(n-1)+F(n-2);
//方法一:递归耗时较长
class Solution {
public int fib(int n) {
if(n<2) return n;
return fib(n-1)+fib(n-2);
}
}
//方法二:滚动数组,耗时较短。
思路:将后一个元素的值转移到前一个元素
class Solution {
public int fib(int n) {
if (n < 2) {
return n;
}
int p = 0, q = 0, r = 1;
for (int i = 2; i <= n; ++i) {
p = q;
q = r;
r = p + q;
}
return r;
}
}
4.泰波那契函数
设F(0)=0; F(1)=1; F(2)=1;
F(n+3)=F(n)+F(n+1)+F(n+2);
n>=0; 返回F(n)。
**思路:**可转化为斐波那契函数的变体F(n)=F(n-1)+F(n-2)+F(n-3);
//第一种方法,用递归,会超时
class Solution {
public int tribonacci(int n) {
if(n==0){
return 0;
}
if(n<3){
return 1;
}
return tribonacci(n-1)+tribonacci(n-2)+tribonacci(n-3);
}
}
//第二种方法,滚动数组
class Solution {
public int tribonacci(int n) {
if(n==0){
return 0;
}
if(n<3){
return 1;
}
int p=0,q=0,t=1,r=1;
for(int i=3;i<=n;i++){
p=q;
q=t;
t=r;
r=p+q+t;
}
return r;
}
}
练习——爬楼梯
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
**思路:**通过列示可以发现规律,第n个值等于前两个值的和,即斐波那契数列。
//滚动数组
class Solution {
public int climbStairs(int n) {
int p=0,q=1,r=1;
for(int i=2;i<=n;i++){
p=q;
q=r;
r=p+q;
}
return r;
}
}
不死神兔
字符串反转
字符串反转的两种方法
//方法1
String str1="Perserve!";
str1= new StringBuilder(str1).reverse().toString();
System.out.println(str1);
//方法2
String str2="Fight!";
StringBuffer rev=new StringBuffer();
for (int i = str2.length()-1; i >=0 ; i--) {
rev.append(str2.charAt(i));
}
System.out.println(rev);