Description

Given an integer rowIndex, return the rowIndexth (0-indexed) row of the Pascal’s triangle.

In Pascal’s triangle, each number is the sum of the two numbers directly above it as shown:

Example 1:

  • Input: rowIndex = 3
  • Output: [1,3,3,1]

Example 2:

  • Input: rowIndex = 0
  • Output: [1]

Example 3:

  • Input: rowIndex = 1
  • Output: [1,1]

Constraints:

  • 0 <= rowIndex <= 33

Follow up: Could you optimize your algorithm to use only 𝑂(rowIndex) extra space?

Submitted Code

class Solution(object):
    def getRow(self, rowIndex):
        """
        :type rowIndex: int
        :rtype: List[int]
        """
        last_row = []

        for row in range(rowIndex + 1):
            current_row = []
            for col in range(row + 1):
                if col == 0 or col == row:
                    current_row.append(1)
                else:
                    current_row.append(last_row[col-1] + last_row[col])
            last_row = current_row

        return last_row

Runtime: 0 ms | Beats 100.00%
Memory: 12.35 MB | Beats 75.38%

Follow up을 충족하는 답안을 만들기 위해서 고민했는데, 그냥 118번에서 했던 코드에서 전체 행을 모두 저장하는 대신 가장 마지막의 행만 저장하도록 바꾸는 것으로 간단하게 해결할 수 있었다.

Other Solutions

1st

from math import comb

class Solution:
    def getRow(self, rowIndex: int) -> List[int]:
        return [comb(rowIndex, i) for i in range(rowIndex + 1)]

time complexity: 𝑂(𝑛)
space complexity: 𝑂(1)

파스칼의 삼각형에서 각 항목을 이항 계수(binomial coefficient)로 표현할 수 있는 것을 활용한 답안이다. math 모듈의 math.comb() 함수를 이용했다. 반환값을 제외하면 추가적인 공간을 사용하지 않는다는 장점이 있다.

rowIndex = 4

C(4, 0) = 4! / 0!(4 - 0)! = 4!/0!(4!) = 1
C(4, 1) = 4! / 1!(4 - 1)! = 4!/1!(3!) = 4
C(4, 2) = 4! / 2!(4 - 2)! = 4!/2!(4!) = 6
C(4, 3) = 4! / 3!(4 - 3)! = 4!/3!(1!) = 4 
C(4, 4) = 4! / 4!(4 - 4)! = 4!/4!(0!) = 1

return [1, 4, 6, 4, 1]

2nd

class Solution:
    def getRow(self, rowIndex: int) -> List[int]:
        res = [1]  # rowIndex가 0이면 [1]
        prev = 1   # 이전 항 값 저장
        
        for k in range(1, rowIndex + 1):                # 1부터 rowIndex까지 반복
            next_val = prev * (rowIndex - k + 1) // k   # 이항 계수 점화식 (// 연산자로 소수점 없이 값 얻기)
            res.append(next_val)
            prev = next_val                             # prev 업데이트
        
        return res

math 모듈없이 이항 계수를 계산한 코드다. 이항 계수 공식을 점화식으로 나타내서 이전 값을 이용해 새로운 값을 계산하는 방법이다. / 연산자로 나누면 float 형이 되기 때문에 // 연산자로 몫만 얻는 것을 볼 수 있다.

이항 계수 공식
C(rowIndex, k) = rowIndex! / k!(rowIndex - k)!

점화식
C(rowIndex, k) = C(rowIndex, k−1) * (rowIndex - k + 1) / k

3rd

class Solution(object):
    def getRow(self, rowIndex):
        row = [1]

        for _ in range(rowIndex):
            row = [left + right for left, right in zip([0]+row, row+[0])]
            
        return row

각 행의 양쪽 끝에 0을 더한다는 아이디어 + zip()을 이용한 예시다.

rowIndex = 4

                                    [1]          
zip([0]+[1]      , [1]+[0])       → [(0,1), (1,0)]
                                    [  1,     1  ]   
zip([0]+[1,1]    , [1,1]+[0])     → [(0,1), (1,1), (1,0)]
                                    [  1,     2,     1  ] 
zip([0]+[1,2,1]  , [1,2,1]+[0])   → [(0,1), (1,2), (2,1), (1,0)]
                                    [  1,     3,     3,     1  ]              
zip([0]+[1,3,3,1], [1,3,3,1]+[0]) → [(0,1), (1,3), (3,3), (3,1), (1,0)]
                                    [  1,     4,     6,     4,     1  ]

return [1, 4, 6, 4, 1]

Leave a comment