Lesson 1
Simple Matrix Operations in Go
Lesson Overview

Welcome to this lesson covering Simple Matrix Operations. This is where we explore the arena of two-dimensional data structures, commonly known as matrices. Matrices play an instrumental role in many domains of programming, such as machine learning, computer vision, and game development, making it important for you to understand how to effectively manipulate and traverse them.

Matrix Review

In Go, matrices can be represented using slices of slices. This allows us to easily manipulate our data structures while retaining flexibility in specifying the size of the matrix dynamically. Here is an example of how you can declare and initialize a 3x3 matrix in Go:

Go
1matrix := [][]int{ 2 {1, 2, 3}, 3 {4, 5, 6}, 4 {7, 8, 9}, 5}

You can access elements of the matrix using indices of the row and column. For example, matrix[1][2] would access the element in the second row and third column, which is 6.

Matrix Traversal Review

We can access the number of rows in a matrix using len(matrix). The number of columns can be determined by the length of any inner slice, such as len(matrix[0]). Traversing a matrix usually involves nested loops. The outer loop normally iterates over the rows, and the inner loop iterates over the columns. Let's take a look at this code that simply prints each element of a matrix.

Go
1for i := 0; i < len(matrix); i++ { 2 for j := 0; j < len(matrix[i]); j++ { 3 fmt.Print(matrix[i][j], " ") 4 } 5 fmt.Println() 6}

Let's break this code down:

Outer Loop

  • This loop iterates over the rows of the matrix.
  • len(matrix) returns the number of rows in the matrix.
  • The variable i is the row index, starting at 0 and incrementing by 1 until it reaches the total number of rows.
Go
1for i := 0; i < len(matrix); i++ {

Inner Loop

  • This loop iterates over the columns of the current row (i).
  • len(matrix[i]) returns the number of columns in the i-th row of the matrix.
  • The variable j is the column index, starting at 0 and incrementing by 1 until it reaches the total number of columns in the current row.
Go
1for j := 0; j < len(matrix[i]); j++ {

Accessing Elements

  • matrix[i][j] accesses the element located at the i-th row and j-th column of the matrix.
  • fmt.Print(matrix[i][j], " ") prints the accessed element, followed by a space " ".
Go
1fmt.Print(matrix[i][j], " ")

Printing Newline

  • We print a newline character, moving the console cursor to the next line.
Go
1fmt.Println()

In summary, the outer loop iterates through each row, while the inner loop iterates through each column of the current row, printing each element followed by a space. After printing all elements in a row, it prints a newline character to start the next row on a new line.

Matrix Search

With this foundation in matrix traversal, let's tackle a common coding interview question. Given a sorted matrix where each row and column is sorted in ascending order, we have to search for a particular target value. One approach is traversing the entire matrix until we find the target value. However, this requires us to potentially search the entire matrix. Let's optimize our approach.

Since the matrix is sorted both row-wise and column-wise, we can leverage this property for an efficient search. Start from the top-right corner of the matrix:

  • If the current element equals the target, you've found the value.
  • If the current element is greater than the target, move left (one column back).
  • If the current element is less than the target, move down (one row forward).

Continue these steps until you either find the target or exhaust the search space. This method ensures that each step narrows down the potential search area efficiently.

Here's how you can implement this in Go:

Go
1package main 2 3import ( 4 "fmt" 5) 6 7func searchMatrix(matrix [][]int, target int) bool { 8 if len(matrix) == 0 || len(matrix[0]) == 0 { 9 return false 10 } 11 12 rows := len(matrix) 13 cols := len(matrix[0]) 14 15 row := 0 16 col := cols - 1 17 18 for row < rows && col >= 0 { 19 if matrix[row][col] == target { 20 return true 21 } else if matrix[row][col] > target { 22 col-- // move left 23 } else { 24 row++ // move down 25 } 26 } 27 28 return false // target not found 29} 30 31func main() { 32 matrix := [][]int{ 33 {1, 4, 7, 11, 15}, 34 {2, 5, 8, 12, 19}, 35 {3, 6, 9, 16, 22}, 36 {10, 13, 14, 17, 24}, 37 {18, 21, 23, 26, 30}, 38 } 39 target := 5 40 41 if searchMatrix(matrix, target) { 42 fmt.Println("Target found in the matrix.") 43 } else { 44 fmt.Println("Target not found in the matrix.") 45 } 46}
Code Breakdown

Let's break down the code step by step:

Function Definition

This line defines the function searchMatrix that returns a bool. The first parameter is a slice of slices of integers, and the second is the target value we are searching for.

Go
1func searchMatrix(matrix [][]int, target int) bool

Check for Empty Matrix

This check ensures that if the matrix is empty or the first row is empty, the function immediately returns false, as there is no element to search.

Go
1if len(matrix) == 0 || len(matrix[0]) == 0 { 2 return false 3}

Determine Dimensions of the Matrix

This step fetches the number of rows and columns in the matrix to use in boundary conditions.

Go
1rows := len(matrix) 2cols := len(matrix[0])

Set Initial Position

Initialize the starting point to the top-right corner of the matrix. row is initialized to 0 and col to the last column index cols - 1.

Go
1row := 0 2col := cols - 1

Start Matrix Traversal

The for loop runs as long as row is less than the number of rows and col is non-negative.

Go
1for row < rows && col >= 0 {

Comparison and Movement

  • If the current element matrix[row][col] is equal to the target, the function returns true.
  • If the current element is greater than the target, move left by decrementing col because all elements to the left are smaller.
  • If the current element is less than the target, move down by incrementing row because all elements below are larger.
Go
1if matrix[row][col] == target { 2 return true 3} else if matrix[row][col] > target { 4 col-- // move left 5} else { 6 row++ // move down 7}

Return Statement

  • If the loop completes and the target is not found, the function returns false.
Go
1return false // target not found

In summary, the searchMatrix function searches for a target value within a two-dimensional matrix where each row and column is sorted in ascending order. By starting from the top-right corner and leveraging the sorted properties, it efficiently narrows the search space by moving left or down based on comparisons.

What's Next?

Once you've absorbed the fundamental concepts of matrices and their operations, we're all set to dive into the practice exercises. We cannot stress enough the importance of practice when it comes to programming. Remember, our goal here is not to brute-force our way through problems, but to build a solid understanding of matrix concepts, improve problem-solving skills, and write code that is not only correct but also efficient and elegant.

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.