LeetCode:Pascal's Triangle II - 帕斯卡三角形2

一、題目名稱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

相關文章
相關標籤/搜索