一、题目名称java
Pascal's Triangle II(帕斯卡三角形2)函数
二、题目地址.net
https://leetcode.com/problems/pascals-triangle-ii/code
三、题目内容blog
英文:Given an index k, return the kth row of the Pascal's triangle.leetcode
中文:给出行数k,返回帕斯卡三角形的第k行开发
例如,k=3时,返回[1,3,3,1]get
四、解题方法1io
帕斯卡三角形也叫杨辉三角形,在LeetCode第118题(Pascal's Triangle)中,已经实现了按杨辉三角形的定义自上到下生成各列。这个方法也能够用于求指定行。class
一段实现此方法的Java代码以下:
import java.util.ArrayList; import java.util.List; /** * 功能说明:LeetCode 119 - Pascal's Triangle II * 开发人员:Tsybius2014 * 开发时间:2015年8月14日 */ public class Solution { /** * 获取帕斯卡三角形的指定行 * @param rowIndex 行数 * @return */ public List<Integer> getRow(int rowIndex) { if (rowIndex < 0) { return null; } ArrayList<Integer> resultList = new ArrayList<Integer>(); //第一行 resultList.add(1); //以后各行 for (int i = 0; i < rowIndex; i++) { resultList = getNextArray(resultList); } return resultList; } /** * 给定帕斯卡三角形的一行数据,获取下一行数据 * @param array 帕斯卡三角形某一行 * @return 帕斯卡三角形的下一行 */ public ArrayList<Integer> getNextArray(ArrayList<Integer> arrayList) { if (arrayList == null) { return null; } ArrayList<Integer> nextList = new ArrayList<Integer>(); nextList.add(1); for (int i = 0; i + 1 < arrayList.size(); i++) { nextList.add(arrayList.get(i) + arrayList.get(i + 1)); } nextList.add(1); return nextList; } }
五、解题方法2
另外一个办法是利用杨辉三角形的特性,即第n行的第k个数字为组合数 C(n-1, k-1),这样只须要写一个计算组合数的函数,调用n次就能够了。不过这里要注意,组合数的计算过程当中,为了防止中间数值过大致使计算结果不精确,能够采用double类型数字存储中间值,且当k>n-k时,将k转换为n-k计算。
一段实现此方法的Java代码以下:
import java.util.ArrayList; import java.util.List; /** * 功能说明:LeetCode 119 - Pascal's Triangle II * 开发人员:Tsybius2014 * 开发时间:2015年8月14日 */ public class Solution { /** * 获取帕斯卡三角形的指定行 * @param rowIndex 行数 * @return */ public List<Integer> getRow(int rowIndex) { int n = rowIndex + 1; ArrayList<Integer> resultList = new ArrayList<Integer>(); for (int k = 1; k <= n; k++) { resultList.add(C(n - 1, k - 1)); } return resultList; } /** * 求组合数 C(n,k) = (n(n-1)(n-2)...(n-k+1))/(k(k-1)(k-2)...1) * @param n C(n,k)中的n * @param k C(n,k)中的k * @return 组合数 */ private int C(int n, int k) { if (k > n - k) { k = n - k; } double numerator = 1.0; double denominator = 1.0; for (int i = 0; i < k; i++) { numerator *= (n - i); denominator *= (k - i); } return (int)(numerator / denominator + 0.5); } }
须要注意的是,由于组合数C(n,k)在k=1到k=n的循环过程当中计算出的值是对称的,为了减小计算量,只须要计算最多n/2+1次组合数就能够了。
一个更好的办法是:
public List<Integer> getRow(int rowIndex) { int n = rowIndex + 1; ArrayList<Integer> resultList = new ArrayList<Integer>(); if (n % 2 == 1) { resultList.add(C(n - 1, n / 2)); } for (int k = n / 2; k > 0; k--) { resultList.add(0, C(n - 1, k - 1)); resultList.add(C(n - 1, k - 1)); } return resultList; }
END