算法 - 递归

162 阅读2分钟

本文为小码哥推出的恋上数据结构与算法笔记,如有兴趣,请报班学习

斐波那契数列

public class Fib {
	public static void main(String[] args) {
		Fib fib = new Fib();
		System.out.println(fib.fib5(5));
		
	}
	
//	 第一种
	int fib0(int n) {
		if (n <= 2) return 1;
		return fib0(n - 2) + fib0(n  - 1) ;
	}
	
//	优化一:利用数组存放计算过的结果,避免重复计算
	int fib1(int n) {
		if (n <= 2) return 1;
		int[] array = new int[n+1];
		array[2] = array[1] = 1;
		return fib1(n, array);
	}
	
	int fib1(int n, int[] array) {
		if (array[n] == 0) {
			array[n] = fib1(n - 1, array) + fib1(n-2, array);
		}
		return array[n];
	}
//	优化二:去递归调用
	int fib2(int n) {
		if (n <= 2) return 1;
		int[] array = new int[n+1];
		array[2] = array[1] = 1;
		for (int i = 3; i <= n; i++) {
			array[i] = array[i-1] + array[i-2];
		}
		return array[n];
	}
//	优化三:滚动数组
	int fib3(int n) {
		if (n <= 2) return 1;
		int[] array = new int[2];
		array[0] = array[1] = 1;
		for (int i = 3; i <= n; i++) {
			array[i%2] = array[(i-1) % 2] + array[(i-2) % 2];
		}
		return array[n % 2];
	}
//	优化四:位运算取代模运算  (对于2的模运算,相当于取2进制的最后一位,相当于位运算的 & 1)
	int fib4(int n) {
		if (n <= 2) return 1;
		int[] array = new int[2];
		array[0] = array[1] = 1;
		for (int i = 3; i <= n; i++) {
			array[i & 1] = array[(i-1) & 1] + array[(i-2) & 1];
		}
		return array[n & 1];
	}
//	优化五:利用两个数字来替换数组
	int fib5(int n) {
		if (n <= 2) return 1;
		int first = 1;
		int second = 1;
		for (int i = 3; i <= n; i++) {
			second = first + second;
			first = second - first;
		}
		return second;
	}
}

爬楼梯

一次可以上一步或者两步台阶,上到第N阶需要多少步? 参考 :算法——爬楼梯问题

下面的图是我偷过来的。。建议看看原文

可以看出是和斐波那契数列相同的迭代

public class ClimbStairs {
	int climbStairs(int n) {
		if (n <= 2) return n;
		return climbStairs(n - 1) + climbStairs(n - 2);
	}
	
}

汉诺塔

思路: 观察可以得出规律是从A柱搬运p(n-1)B柱,将p(n)A柱搬运到C柱,将p(n-1)B柱搬运到C

public class Hanoi {
	public static void main(String[] args) {
		new Hanoi().hanoi(3, "A", "B", "C");
	}
	
	/**
	 * 将 n 个碟子从 p1 挪动到 p3
	 * @param p2 中间的柱子
	 */
	void hanoi(int n, String p1, String p2, String p3) {
		if (n <= 1) {
			move(n, p1, p3);
			return;
		}
		hanoi(n-1, p1, p3, p2);
		move(n, p1, p3);
		hanoi(n-1, p2, p1, p3);
	}
	
	/**
	 * 将 no 号盘子从 from 移动到 to
	 * @param no
	 * @param from
	 * @param to
	 */
	void move(int no, String from, String to) {
		System.out.println("将" + no + "号盘子从" + from + "移动到" + to);
	}
}