leetcode刷题记录-119. Pascal's Triangle II

leetcode刷题记录-119. Pascal’s Triangle II

1.题目要求

  Given an index k, return the kth row of the Pascal’s triangle.
  For example, given k = 3,
  Return [1,3,3,1].
  Note:
  Could you optimize your algorithm to use only O(k) extra space?


2.解决思路

  关键还是杨辉三角的性质:每个数字等于上一行的左右两个数字之和,即第n+1行的第i个数等于第n行的第i-1个数和第i个数之和
  思路一:第n行的第m个数可表示为 C(n-1,m-1),即为从n-1个不同元素中取m-1个元素的组合数,且第m个数和第n-m+1个数相等,因此可以根据该公式计算出来特定行的每个元素
  代码实现:
  

vector<int> getRow_limit(int rowIndex) //rowIndex从0开始计数
{
    //第n行的m个数可表示为 C(n-1,m-1),即为从n-1个不同元素中取m-1个元素的组合数,且第m个数和第n-m+1个数相等
    int i = 0, j = rowIndex;
    int k, temp_top, temp_down , mul_top, mul_down;
    vector<int> output(rowIndex + 1);
    while (i <= j)
    {
        mul_top = mul_down = 1;//每次计算前要先初始化

        if (i == 0)
            mul_top = mul_down = 1;
        else
        {
            for (k = 0; k < i; k++) //计算C (rowIndex i),i代表分母有几个元素相乘
            {
                temp_top = rowIndex - k;
                mul_top *= temp_top;//计算分子

                temp_down = k+1;
                mul_down *= temp_down;
            }
        }
        output[i] = output[j] = mul_top / mul_down;
        i++;
        j--;

    }
    return output;

}

  这种实现的问题在于当rowIndex比较大的时候会因为int的长度不够而越界,从而计算出错误的结果(提交的时候当rowIndex=18的时候中间的那个元素出来的结果就是错的了…..)
  于是把while循环里面的语句稍微修改了一下,如下:
  

    while (i <= j)
    {
        mul_top = mul_down = 1;//每次计算前要先初始化

        if (i == 0)
            mul_top = mul_down = 1;
        else
        {
            for (k = 0; k < i; k++) //计算C (rowIndex i),i代表分母有几个元素相乘
            {
                temp_top = rowIndex - k;
                mul_top *= temp_top;//计算分子

                temp_down = k + 1;
                mul_top /= temp_down;
            }
        }
        output[i] = output[j] = mul_top;
        i++;
        j--;

    }

  和上面的实现相比稍微好了一些,但是当数字过大的时候还是会出现同样的问题(提交的时候当rowIndex=30的时候有错…
 


 思路二:参考别人的代码,觉得思路确实很巧妙,而且没有开辟额外的空间,先贴代码
  代码实现:

vector<int> getRow(int rowIndex) //rowIndex从0开始计数
    {
        int row,col;
        vector<int> output(rowIndex + 1,0);
        output[0]=1;//第一个元素初始化为1
        for(row=0;row<=rowIndex;row++)
        {
            for(col=row;col>=1;col--)
            {
                output[col]=output[col]+output[col-1];//每行从后往前计算,利用杨辉三角的性质,第n行的第i个元素等于第n-1行的第i个和第i-1个元素之和
            }

        }
        return output;
    }

  这里的实现是先根据rowIndex确定要返回的vector的长度,然后也是利用杨辉三角的性质一行一行的进行计算,而且每行是从末尾的元素开始计算的.
  例如n=5,当计算到第3行时,vector里面存放的依次是[1 2 1 0 0],计算第4行的时候首先计算最后一个元素output[3]=output[3]+output[2],因为上一行的元素已经按顺序存放在output前面,所以直接这样引用即可,不过要注意output[3]此时还没有计算,所以默认值应该置为0,而每行的第一个数一定是1,也就是代码中一开始就初始化的output[0]=1,因此循环的时候让col>=1就行了.
  这样计算下来就ok了~~,相比于输出整个杨辉三角,时间复杂度是一样的,但是空间复杂度要小很多..

你可能感兴趣的:(leetcode,cpp)