首页 > 试题广场 >

杨辉三角-ii

[编程题]杨辉三角-ii
  • 热度指数:14871 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
给出一个索引k,返回杨辉三角的第k行
例如,k=3,
返回[1,3,3,1].
备注:
你能将你的算法优化到只使用O(k)的额外空间吗?
示例1

输入

3

输出

[1,3,3,1]
class Solution {
public:
    vector<int> getRow(int rowIndex) {
        vector<int> dp(rowIndex+1,1);
        for(int i=2;i<=rowIndex;i++)
        	for(int j=i-1;j>0;j--)
        		dp[j] = dp[j] + dp[j-1];
        return dp;        	
    }
};

发表于 2017-08-12 00:59:24 回复(0)
更多回答
//合理规划dp转移方向降低一个维度
class Solution {
public:
    vector<int> getRow(int rowIndex) {
         vector<int> dp(rowIndex+1,0);
         dp[0]=1;
         for(int i=1;i<=rowIndex;i++)
             for(int j=i;j>=1;j--)
                 dp[j]+=dp[j-1];
         return dp;
     }
};

发表于 2017-08-23 09:16:39 回复(1)
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> getRow(int rowIndex) {
        ArrayList<Integer> row=new ArrayList<Integer>();
        rowIndex++;
		if(rowIndex==0)
			return row;
		row.add(1);
		for(int i=1;i<rowIndex;i++)
		{
			for(int j=i-1;j>0;j--)
			{
				row.set(j, row.get(j-1)+row.get(j));				
			}
			row.add(1);
		}
		return row;
    }
}

发表于 2017-05-24 11:06:27 回复(3)
//  从后往前迭代
class Solution {
public:
vector<int> getRow(introwIndex) {
vector<int> dp(rowIndex+1, 1);
for(inti=2; i<rowIndex+1; i++) {
for(intj=i-1; j>0; j--)
dp[j] = dp[j]+dp[j-1];
}
returndp;
}
};


编辑于 2017-08-01 19:26:36 回复(0)
/**
 * 119. Pascal's Triangle II
 * 杨辉三角 II
 * 给定一个非负索引 k,其中 k ≤ 33,返回杨辉三角的第 k 行。
 * 在杨辉三角中,每个数是它左上方和右上方的数的和。
 * 示例: 输入: 3 输出: [1,3,3,1]
 */
public class Solution {
    public static void main(String[] args) {
        Solution solution = new Solution();
        List<Integer> result = solution.getRow(4);
        System.out.println(result.toString());
    }

    public List<Integer> getRow(int rowIndex) {

        if (rowIndex < 0) {
            return null;
        }
        List<Integer> result = new ArrayList<>();
        result.add(1);
        for (int i = 1; i <= rowIndex; i++) {
            for (int j = result.size() - 2; j >= 0; j--) {
                result.set(j + 1, result.get(j) + result.get(j + 1));
            }
            result.add(1);
        }

        return result;

    }

}
发表于 2018-08-09 23:12:04 回复(0)
解法一:利用规律每个数字等于上一行的左右两个数字之和。
import java.util.ArrayList;
 
public class Solution {
    public ArrayList<Integer> getRow(int rowIndex) {
        ArrayList<Integer> list = new ArrayList<>();
        for(int i = 0; i <= rowIndex;i ++){
            list.add(1);
        }
        for(int i = 0; i <= rowIndex; i++){
        //从后往前遍历,防止上一行的左右两个数中的左边数在使用时已被更改
            for(int j = i; j >= 0; j--){
                if(j == i || j == 0){
                    continue;
                }
                else{
                    list.set(j, list.get(j-1) + list.get(j));
                }
            }
        }
        return list;
    }
}

解法二
利用规律,第n行的第1个数为1,第二个数为1×(n-1),第三个数为1×(n-1)×(n-2)/2,第四个数为1×(n-1)×(n-2)/2×(n-3)/3…依此类推。
import java.util.ArrayList;
 
public class Solution {
    public ArrayList<Integer> getRow(int rowIndex) {
        ArrayList<Integer> list = new ArrayList<>();
        int n = rowIndex + 1;
        //防止溢出,使用long
        long number = 1;
        for(int i = 1; i <= n; i++){
           list.add((int)number);
           number = number * (n - i) / i;
        }
        return list;
    }
}
编辑于 2019-07-25 12:31:59 回复(1)
//思路:从后往前计算,从而避免了之前的数据被覆盖。满足空间复杂度为O(n)
public ArrayList<Integer> getRow(int rowIndex) {
        ArrayList<Integer> row=new ArrayList<>();
        if(rowIndex<0) return row;
        for(int i=0;i<rowIndex+1;i++){
            for(int j=i-1;j>0;j--){
                row.set(j,row.get(j)+row.get(j-1));
            }
            row.add(1);
        }
        return row;
    }

发表于 2017-07-17 20:28:45 回复(1)

比各位的还要快一点点 由于杨辉三角是对称的
只要dp一半就可以了
ps:一开始赋初值为1简化运算

class Solution {
public:
    vector<int> getRow(int rowIndex) {
        vector<int> res(rowIndex + 1, 1);
        for(int i = 1; i < rowIndex; i++)
            for(int j = (i + 1)/2; j >= 1; j--)
                res[i + 1 - j] = res[j] += res[j-1];          
        return res;
    }
};
编辑于 2019-05-04 11:20:29 回复(0)
class Solution {
public:
    vector<int> getRow(int rowIndex) {
        vector<int>res;
        int dp[rowIndex+1];
        memset(dp,0,sizeof(dp));
        dp[0]=1;
        for(int i=0;i<rowIndex;i++){
          for(int j=i+1;j>=1;j--){
             dp[j]+=dp[j-1];
         }   
        }
        for(int i=0;i<rowIndex+1;i++)
            res.push_back(dp[i]);
        return res;
    }
};
类似dp的滚动数组
编辑于 2016-06-11 16:40:51 回复(0)
import java.util.*;
public class Solution {
    public ArrayList<Integer> getRow(int rowIndex) {
        ArrayList<Integer> list = new ArrayList<>(rowIndex+1);
        list.add(1);
        for(int i = 1; i <= rowIndex; i++){
            list.add(0);
        };
        for(int i = 1; i <= rowIndex; i++){
            int tmp = 1;
            for(int j = 1; j <= i; j++ ){
                int now = tmp+list.get(j);
                tmp = list.get(j);
                list.set(j, now);
            }
        }
        return list;
    }
}

发表于 2020-01-10 20:05:47 回复(0)
此类问题,要想直接写出完美的答案,有一定难度,下面是我逐步优化得到的三种答案:
//递归的方式
    vector<int> getRow(int rowIndex) {
        vector<int> res;
        if (rowIndex == 0){
            res.push_back(1);
            return res;
        }
        res.push_back(1);
        vector<int> upper=getRow(rowIndex-1);
        for (int i = 1; i < rowIndex ; ++i){
            res.push_back(upper[i-1] + upper[i]);
        }
        res.push_back(1);
        return res;
    }
    //动态规划--初级版本,空间复杂度O(k^2)
    vector<int> getRow(int rowIndex) {
        vector<vector<int>>dp(rowIndex+1, vector<int>(rowIndex+1,1));
        for (int i = 2; i < rowIndex+1; ++i){
            for (int j = 1; j < i; ++j){
                dp[i][j] = dp[i-1][j-1] + dp[i-1][j];
            }
        }
        return dp[rowIndex];
    }
    //动态规划--最终版本,空间复杂度O(k)
    vector<int> getRow(int rowIndex) {
        vector<int>dp(rowIndex+1,1);
        for (int i = 2; i < rowIndex+1; ++i){
            for (int j = i-1; j >=1; --j){
                dp[j] = dp[j-1] + dp[j];
            }
        }
        return dp;
    }
发表于 2019-12-06 10:33:21 回复(1)
定义2个长度为k+1的数组,空间复杂度是O(k)级别,两个数组交替更新数据,最后一趟数组刚好填满,将数组用ArrayList形式返回即可,代码如下:
import java.util.*;
public class Solution {
    public ArrayList<Integer> getRow(int rowIndex) {
        int a[] = new int[rowIndex+1];
        int b[] = new int[rowIndex+1];
        a[0] = 1;
        int indexa = 1;
        int indexb = 0;
        int index=1;//偶数行
        while(index <= rowIndex){
            if(index%2==0){
                for(int i=0;i<=indexb;i++)
                    if(i==0 || i==indexb)
                        a[i]=1;
                    else
                        a[i]=b[i]+b[i-1];
                indexa = indexb+1;
            }else{
                for(int i=0;i<=indexa;i++)
                    if(i==0 || i==indexa)
                        b[i]=1;
                    else
                        b[i]=a[i]+a[i-1];
                indexb = indexa+1;
            }
            index++;
        }
        ArrayList<Integer> list = new ArrayList<Integer>();
        if(rowIndex%2==0)
            for(int i=0;i<indexa;i++)
                list.add(a[i]);
        else
            for(int i=0;i<indexb;i++)
                list.add(b[i]);
        return list;
    }
}


编辑于 2018-09-08 14:28:15 回复(0)

O(k)做法。
杨辉三角,第n行第m个数的值为C(m-1,n-1).
用double来进行乘除运算,会出现精度问题,
所以我们要进行精度控制,若大于等于eps我们则向上取整,若小与我们则向下取整即可。

public ArrayList<Integer> getRow(int rowIndex) {
        double eps=1e-6;
        ArrayList<Integer> res=new ArrayList<Integer>();
        if(rowIndex==0){
            res.add(1);
            return res;
        }
        rowIndex+=1;
        res.add(1);
        double up;
        double down;
        double re=1;
        for (int i = 2; i <= rowIndex-1; i++) {
            down=i-1;
            up=rowIndex-i+1;
            re=re/down*up; 
            if(re-(int)re<eps){  
                re=Math.floor(re);
            }else{
                re=Math.ceil(re);
            }
            res.add((int) re);
        }
        res.add(1);
        return res;
    }
编辑于 2018-08-21 17:18:53 回复(1)
class Solution {
public:
    //看大家都是直接用数组搞定的,我这里来一种稍微麻烦的一种做法,
    //主要是根据杨辉三角的性质来做:1、第k行的数字个数为k;2、第n行的
    //第m个数为C(n-1,m-1),即为从n-1个不同元素中取m-1个元素的组合数。
    long permutation(int n,int m)
    {
         //递归求解组合数的函数
        if(m==0)
        {
            return 1;
        }else if(m==1)
        {
            return n;
        }else
            return n*permutation(n-1,m-1)/m;
    }
    vector<int> getRow(int rowIndex) {
        if(rowIndex<0)
            return vector<int>();
        vector<int> vRes;
        for(int i=0;i<=rowIndex;i++)
        {
            vRes.push_back(permutation(rowIndex,i));
        }
        return vRes;
    }
};

编辑于 2018-08-15 20:15:02 回复(0)
class Solution {
public:
    vector<int> getRow(int rowIndex) {
        vector<int> result(rowIndex+1,0);
        result[0]=1;
        int flag=1;
        while(flag<=rowIndex){
           for(int i=flag-1;i>=1;--i)
           {
               result[i]=result[i-1]+result[i];
           }
           result[flag]=1;
            ++flag;
        }
        return result;
    }
};
发表于 2018-05-10 09:48:11 回复(0)
class Solution {
public:
    vector<int> getRow(int rowIndex) {
        vector<int> result[2];
        int flag = 0;
        result[flag].push_back(1);
        for (int i = 1; i <= rowIndex; ++i) {
            int t_falg = flag ^ 1;
            result[t_falg].clear();
            for (int j = 0; j <= i; ++j) {
                if (j == 0 || j == i) {
                    result[t_falg].push_back(1);
                }
                else {
                    result[t_falg].push_back(result[flag][j-1] + result[flag][j]);
                }
            }
            flag ^= 1;
        }
        return result[flag];
    }
};
发表于 2017-10-02 14:28:20 回复(0)
import java.util.ArrayList;
public class Solution {
    
    ArrayList<Integer> result=null;
    
    public ArrayList<Integer> getRow(int rowIndex) {
        
        if(rowIndex<0){
            return result;
        }
        
        ArrayList<Integer> list=new ArrayList<Integer>();
        list.add(1);
        result=list;
        
        if(rowIndex==0){
            return result;
        }
        
        generateCore(1,rowIndex);
        
        return result;
        
        
    }
    
    
    public void generateCore(int index,int numRows) {
        
        if(numRows+1==index){
            
            return;
            
        }
        
        ArrayList<Integer> list=new ArrayList<Integer>();
        
        list.add(1);
        
        for(int i=0;i<index-1;i++){
            
            list.add( result.get(i)+result.get(i+1) );
            
        }
        
        
        list.add(1);
        
        result=list;
        
        generateCore(index+1,numRows);
    }
    
}
发表于 2017-08-12 20:04:28 回复(0)
    public ArrayList<Integer> getRow(int rowIndex) {
        ArrayList<Integer> list =  new ArrayList<Integer>();
        for(int i=0;i<=rowIndex;i++){
            if(i==0) {list.add(1);continue;}
            for(int j=0;j<list.size()-1;j++){
                int m=list.get(j+1);
                list.set(j+1,list.get(0)+list.get(j+1));
                list.set(0,m);
            }
            list.set(0,1);
            list.add(1);
        }
        return list;
    }

发表于 2017-07-24 16:39:15 回复(0)
public ArrayList<Integer> getRow (int rowIndex) {
        // write code here
        //杨辉三角  [1] = 第0行
        ArrayList<Integer> list = new ArrayList<Integer>();
        if(rowIndex==0)  {list.add(1);return list;}
        ArrayList<Integer> temp = getRow(rowIndex-1);
        for(int i=0;i<=rowIndex;i++){
            if(i==0 || i==rowIndex){
                list.add(1);
            }else{
                list.add(temp.get(i-1)+temp.get(i));
            }
        }
        return list;
    }
发表于 2022-01-09 23:29:09 回复(0)

做这种模拟类型的算法题,有三个要诀:快、准、狠,缺一不可:

  1. 快,时间控制在30分钟以内,这样才能预留充分时间给后面的题目
  2. 准,找准边界条件
  3. 狠,一旦有把握,毫不犹豫的动手写代码

此类题目很重要的几个特性:🅐对称 🅑旋转 🅒重复...,利用这些特性可以大大减少代码量

由于模拟类型题目变化多端,要做到快准狠实属不易,需要我们快速分析,快速找规律。以本题为例,当rowIndex=5时,数组为1 5 10 10 5 1,我们用1初始化这个数组,再一步步得出结果:

  1. 1 1 1 1 1 1 边界为(0, 0) 中间节点为0
  2. 1 1 1 1 1 1 边界为(0, 1) 中间节点为0
  3. 1 2 1 1 1 1 边界为(0, 2) 中间节点为1
  4. 1 3 3 1 1 1 边界为(0, 3) 中间节点为1
  5. 1 4 6 4 1 1 边界为(0, 4) 中间节点为2
  6. 1 5 10 10 5 1 边界为(0, 5) 中间节点为2

由于在边界内部是对称的,我萌可以从中间节点向一侧边界遍历,循环几遍即可得到最终的结果。

//
// Created by jt on 2020/9/2.
//
#include <vector>
using namespace std;

class Solution {
public:
    /**
     *
     * @param rowIndex int整型
     * @return int整型vector
     */
    vector<int> getRow(int rowIndex) {
        // write code here
        vector<int> res(rowIndex+1, 1);
        for (int i = 2; i <= rowIndex; ++i) {
            for (int j = i / 2; j > 0; --j) {
                res[j] = res[j] + res[j-1];
                res[i-j] = res[j];    // 对称
            }
        }
        return res;
    }
};
发表于 2020-09-02 11:53:24 回复(0)