爬楼梯 - 矩阵快速幂

1.题目描述

假设你正在爬楼梯。需要n阶你才能到达楼顶。
每次你可以爬12个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定n是一个正整数。
示例 1:

输入: 2
输出: 2
解释: 有两种方法可以爬到楼顶。
1.  1 阶 + 1 阶
2.  2 阶

示例 2:

输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶。
1.  1 阶 + 1 阶 + 1 阶
2.  1 阶 + 2 阶
3.  2 阶 + 1 阶

2.题解

2.1 矩阵快速幂

public int climbStairs(int n) {
	int[][] q = {{1, 1}, {1, 0}};
	int[][] res = pow(q, n);
	return res[0][0];
}

public int[][] pow(int[][] a, int n) {
	int[][] ret = {{1, 0}, {0, 1}};
	while (n > 0) {
		if ((n & 1) == 1) {
			ret = multiply(ret, a);
		}
		n >>= 1;
		a = multiply(a, a);
	}
	return ret;
}

public int[][] multiply(int[][] a, int[][] b) {
	int[][] c = new int[2][2];
	for (int i = 0; i < 2; i++) {
		for (int j = 0; j < 2; j++) {
			c[i][j] = a[i][0] * b[0][j] + a[i][1] * b[1][j];
		}
	}
	return c;
}

快速幂(Exponentiation by squaring,平方求幂)是快速计算一个数的大正整数幂的一般方法。
相关阅读:

矩阵快速幂指的是底数为矩阵的快速幂。那么矩阵是什么?矩阵是为了解决什么问题?
相关阅读:

由递推关系得:

\[\begin{bmatrix} f(n+1)\\ f(n) \end{bmatrix}= \begin{bmatrix} 1 & 1\\ 1 & 0 \end{bmatrix} ^{n} \begin{bmatrix} f(1)\\ f(0) \end{bmatrix} \]

n = 5时,

\[\begin{bmatrix} f(6)\\ f(5) \end{bmatrix}= \begin{bmatrix} 8 & 5\\ 5 & 3 \end{bmatrix} \begin{bmatrix} f(1)\\ f(0) \end{bmatrix} \]

最终结果取res[0][0],于是,这里\(f(5)=8\),但这是为什么呢?
注意到\(f(0)=1\)\(f(1)=1\),所以\(f(6)=8+5\)\(f(5)=5+3\)
这里的矩阵第一行第一列的元素8为什么刚好等于第二行元素的和(5+3)?

n=1时,\(\begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix}^{1}=\begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix}\)
n=2时,\(\begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix}^{2}=\begin{bmatrix} 2 & 1 \\ 1 & 1 \end{bmatrix}\)
n=3时,\(\begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix}^{3}=\begin{bmatrix} 3 & 2 \\ 2 & 1 \end{bmatrix}\)
n=4时,\(\begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix}^{4}=\begin{bmatrix} 5 & 3 \\ 3 & 2 \end{bmatrix}\)
n=5时,\(\begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix}^{5}=\begin{bmatrix} 8 & 5 \\ 5 & 3 \end{bmatrix}\)

假设\(\begin{bmatrix} a & b \\ c & d \end{bmatrix}=\begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix}\),于是有:

\(\begin{bmatrix} a & b \\ c & d \end{bmatrix}\begin{bmatrix} a & b \\ c & d \end{bmatrix}=\begin{bmatrix} a+b & a \\ c+d & c \end{bmatrix}\)

\(\begin{bmatrix} a & b \\ c & d \end{bmatrix}\begin{bmatrix} a & b \\ c & d \end{bmatrix}\begin{bmatrix} a & b \\ c & d \end{bmatrix}=\begin{bmatrix} a+b & a \\ c+d & c \end{bmatrix}\begin{bmatrix} a & b \\ c & d \end{bmatrix}=\begin{bmatrix} 2a+b & a+b \\ 2c+d & c+d \end{bmatrix}\)

这里很好地解释了当n=5时,为什么矩阵第一行第一列的元素8为什么刚好等于第二行元素的和(5+3)。
因为矩阵第一行第一列的元素值为上一个矩阵的第一行元素的和,但为什么矩阵第二行元素刚好是上一个矩阵的第一行元素呢?
矩阵第二行第一列的元素值为上一个矩阵的第二行元素的和,而矩阵第二行第二列的元素为上一个矩阵的第二行第一列的元素。
结合第一个矩阵为\(\begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix}\),所以矩阵第二行元素刚好是上一个矩阵的第一行元素。

参考:

posted @ 2021-01-08 11:29  gzhjj  阅读(240)  评论(0编辑  收藏  举报