给出一个索引k,返回杨辉三角的第k行
例如,k=3,
返回[1,3,3,1].
备注:
你能将你的算法优化到只使用O(k)的额外空间吗?
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;
}
}
/**
* 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;
}
}
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;
}
}
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;
}
} //思路:从后往前计算,从而避免了之前的数据被覆盖。满足空间复杂度为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;
}
比各位的还要快一点点 由于杨辉三角是对称的
只要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;
}
};
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;
}
};
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;
}
} 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;
}
} 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;
}
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;
}
};
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];
}
};
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;
} 做这种模拟类型的算法题,有三个要诀:快、准、狠,缺一不可:
此类题目很重要的几个特性:🅐对称 🅑旋转 🅒重复...,利用这些特性可以大大减少代码量
由于模拟类型题目变化多端,要做到快准狠实属不易,需要我们快速分析,快速找规律。以本题为例,当rowIndex=5时,数组为1 5 10 10 5 1,我们用1初始化这个数组,再一步步得出结果:
1 1 1 1 1 1 边界为(0, 0) 中间节点为0 1 1 1 1 1 1 边界为(0, 1) 中间节点为0 1 2 1 1 1 1 边界为(0, 2) 中间节点为1 1 3 3 1 1 1 边界为(0, 3) 中间节点为1 1 4 6 4 1 1 边界为(0, 4) 中间节点为2 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;
}
};