Build the first numRows rows. Every row starts and ends with 1, and every
interior cell is the sum of the two above it.
1 1 1 1 2 1 1 3 3 1 1 4 6 4 1Straight from the definition
Row 1 is closed with a 1. Every row starts and ends with one, which is why the inner loop only ever fills the middle.
func generate(numRows int) [][]int { var result = [][]int{}
result = append(result, []int{1})
for i := 1; i < numRows; i++ { var row = []int{}
row = append(row, 1)
for j := 1; j < i; j++ { row = append(row, result[i-1][j-1]+result[i-1][j]) }
row = append(row, 1)
result = append(result, row) }
return result}time and output — which is optimal, because that is how many numbers there are.
The edges, and why the loop skips them
The inner loop runs j from 1 to i-1 — never touching the ends. Those are
appended unconditionally instead, because T[i-1][j-1] and T[i-1][j] do not
both exist at the boundary.
That is the usual DP shape: a recurrence for the interior, base cases for the edges. Trying to make one expression cover both means bounds-checking on every cell.
Preallocating
Each row’s length is known before it is built — row i has i+1 entries — so
the appends can be replaced with an allocation:
func generate(numRows int) [][]int { result := make([][]int, numRows)
for i := range result { row := make([]int, i+1) row[0], row[i] = 1, 1
for j := 1; j < i; j++ { row[j] = result[i-1][j-1] + result[i-1][j] }
result[i] = row }
return result}Same complexity, no reallocation as the rows grow, and it handles numRows = 0
correctly for free — make([][]int, 0) and a loop that never runs. Knowing the
size up front is the same habit that
concatenation of array is really about.
The related questions
Pascal’s Triangle II asks for row k alone, in space. You can build
it in place if you fill right to left, so each cell is updated before the
value it depends on is overwritten. Left to right destroys T[i-1][j-1] before
you use it — the same read-before-write ordering as the in-place suffix walk in
replace elements.
Any single entry is , computable directly without the table at all. The triangle is only the efficient route when you want many entries.