diff --git a/go/Hash Maps and Sets/geometric_sequence_triplets.go b/go/Hash Maps and Sets/geometric_sequence_triplets.go new file mode 100644 index 0000000..c4d55a6 --- /dev/null +++ b/go/Hash Maps and Sets/geometric_sequence_triplets.go @@ -0,0 +1,25 @@ +func geometricSequenceTriplets(nums []int, r int) int { + // Use 'map' to ensure the default value of 0 is returned when + // accessing a key that doesn’t exist in the hash map. This effectively sets + // the default frequency of all elements to 0. + leftMap := make(map[int]int) + rightMap := make(map[int]int) + count := 0 + // Populate 'rightMap' with the frequency of each element in the array. + for _, x := range nums { + rightMap[x]++ + } + // Search for geometric triplets that have x as the center. + for _, x := range nums { + // Decrement the frequency of x in 'rightMap' since x is now being + // processed and is no longer to the right. + rightMap[x]-- + if x%r == 0 { + count += leftMap[x/r] * rightMap[x*r] + } + // Increment the frequency of x in 'leftMap' since it'll be a part of the + // left side of the array once we iterate to the next value of x. + leftMap[x]++ + } + return count +} diff --git a/go/Hash Maps and Sets/longest_chain_of_consecutive_numbers.go b/go/Hash Maps and Sets/longest_chain_of_consecutive_numbers.go new file mode 100644 index 0000000..dcfa30a --- /dev/null +++ b/go/Hash Maps and Sets/longest_chain_of_consecutive_numbers.go @@ -0,0 +1,27 @@ +func longestChainOfConsecutiveNumbers(nums []int) int { + if len(nums) == 0 { + return 0 + } + numSet := make(map[int]bool) + for _, num := range nums { + numSet[num] = true + } + longestChain := 0 + for num := range numSet { + // If the current number is the smallest number in its chain, search for + // the length of its chain. + if !numSet[num-1] { + currentNum := num + currentChain := 1 + // Continue to find the next consecutive numbers in the chain. + for numSet[currentNum+1] { + currentNum++ + currentChain++ + } + if currentChain > longestChain { + longestChain = currentChain + } + } + } + return longestChain +} diff --git a/go/Hash Maps and Sets/longest_chain_of_consecutive_numbers_brute_force.go b/go/Hash Maps and Sets/longest_chain_of_consecutive_numbers_brute_force.go new file mode 100644 index 0000000..8712605 --- /dev/null +++ b/go/Hash Maps and Sets/longest_chain_of_consecutive_numbers_brute_force.go @@ -0,0 +1,31 @@ +func longestChainOfConsecutiveNumbersBruteForce(nums []int) int { + if len(nums) == 0 { + return 0 + } + longestChain := 0 + // Look for chains of consecutive numbers that start from each number. + for _, num := range nums { + currentNum := num + currentChain := 1 + // Continue to find the next consecutive numbers in the chain. + for contains(nums, currentNum+1) { + currentNum++ + currentChain++ + } + if currentChain > longestChain { + longestChain = currentChain + } + } + return longestChain +} + +// In the Python code, the while loop checks (current_num +1) in nums. +// So the helper function 'contains' is needed. +func contains(nums []int, target int) bool { + for _, n := range nums { + if n == target { + return true + } + } + return false +} diff --git a/go/Hash Maps and Sets/pair_sum_unsorted.go b/go/Hash Maps and Sets/pair_sum_unsorted.go new file mode 100644 index 0000000..77f9f5f --- /dev/null +++ b/go/Hash Maps and Sets/pair_sum_unsorted.go @@ -0,0 +1,11 @@ +func pairSumUnsorted(nums []int, target int) []int { + hashmap := make(map[int]int) + for i, x := range nums { + complement := target - x + if idx, exists := hashmap[complement]; exists { + return []int{idx, i} + } + hashmap[x] = i + } + return nil +} diff --git a/go/Hash Maps and Sets/pair_sum_unsorted_two_pass.go b/go/Hash Maps and Sets/pair_sum_unsorted_two_pass.go new file mode 100644 index 0000000..cffa765 --- /dev/null +++ b/go/Hash Maps and Sets/pair_sum_unsorted_two_pass.go @@ -0,0 +1,15 @@ +func pairSumUnsortedTwoPass(nums []int, target int) []int { + numMap := make(map[int]int) + // First pass: Populate the hash map with each number and its index. + for i, num := range nums { + numMap[num] = i + } + // Second pass: Check for each number's complement in the hash map. + for i, num := range nums { + complement := target - num + if idx, ok := numMap[complement]; ok && idx != i { + return []int{i, idx} + } + } + return nil +} diff --git a/go/Hash Maps and Sets/verify_sudoku_board.go b/go/Hash Maps and Sets/verify_sudoku_board.go new file mode 100644 index 0000000..083385b --- /dev/null +++ b/go/Hash Maps and Sets/verify_sudoku_board.go @@ -0,0 +1,47 @@ +func verifySudokuBoard(board [][]int) bool { + // Create hash sets for each row, column, and subgrid to keep + // track of numbers previously seen on any given row, column, or + // subgrid. + rowSets := make([]map[int]struct{}, 9) + columnSets := make([]map[int]struct{}, 9) + subgridSets := make([][]map[int]struct{}, 3) + + for i := range rowSets { + rowSets[i] = make(map[int]struct{}) + } + for i := range columnSets { + columnSets[i] = make(map[int]struct{}) + } + for i := range subgridSets { + subgridSets[i] = make([]map[int]struct{}, 3) + for j := range subgridSets[i] { + subgridSets[i][j] = make(map[int]struct{}) + } + } + + for r := 0; r < 9; r++ { + for c := 0; c < 9; c++ { + num := board[r][c] + if num == 0 { + continue + } + // Check if 'num' has been seen in the current row, + // column, or subgrid. + if _, exists := rowSets[r][num]; exists { + return false + } + if _, exists := columnSets[c][num]; exists { + return false + } + if _, exists := subgridSets[r/3][c/3][num]; exists { + return false + } + // If we passed the above checks, mark this value as seen + // by adding it to its corresponding hash sets. + rowSets[r][num] = struct{}{} + columnSets[c][num] = struct{}{} + subgridSets[r/3][c/3][num] = struct{}{} + } + } + return true +} diff --git a/go/Hash Maps and Sets/zero_striping.go b/go/Hash Maps and Sets/zero_striping.go new file mode 100644 index 0000000..e9687d1 --- /dev/null +++ b/go/Hash Maps and Sets/zero_striping.go @@ -0,0 +1,56 @@ +func zeroStriping(matrix [][]int) { + if len(matrix) == 0 || len(matrix[0]) == 0 { + return + } + m, n := len(matrix), len(matrix[0]) + // Check if the first row initially contains a zero. + firstRowHasZero := false + for c := 0; c < n; c++ { + if matrix[0][c] == 0 { + firstRowHasZero = true + break + } + } + // Check if the first column initially contains a zero. + firstColHasZero := false + for r := 0; r < m; r++ { + if matrix[r][0] == 0 { + firstColHasZero = true + break + } + } + // Use the first row and column as markers. If an element in the + // submatrix is zero, mark its corresponding row and column in the + // first row and column as 0. + for r := 1; r < m; r++ { + for c := 1; c < n; c++ { + if matrix[r][c] == 0 { + matrix[0][c] = 0 + matrix[r][0] = 0 + } + } + } + // Update the submatrix using the markers in the first row and + // column. + for r := 1; r < m; r++ { + for c := 1; c < n; c++ { + if matrix[0][c] == 0 || matrix[r][0] == 0 { + matrix[r][c] = 0 + } + } + } + // If the first row had a zero initially, set all elements in the + // first row to zero. + if firstRowHasZero { + for c := 0; c < n; c++ { + matrix[0][c] = 0 + } + } + // If the first column had a zero initially, set all elements in + // the first column to zero. + if firstColHasZero { + for r := 0; r < m; r++ { + matrix[r][0] = 0 + } + } +} diff --git a/go/Hash Maps and Sets/zero_striping_hash_sets.go b/go/Hash Maps and Sets/zero_striping_hash_sets.go new file mode 100644 index 0000000..f1351b4 --- /dev/null +++ b/go/Hash Maps and Sets/zero_striping_hash_sets.go @@ -0,0 +1,30 @@ +func zeroStripingHashSets(matrix [][]int) { + if len(matrix) == 0 || len(matrix[0]) == 0 { + return + } + m, n := len(matrix), len(matrix[0]) + zeroRows := make(map[int]struct{}) + zeroCols := make(map[int]struct{}) + // Pass 1: Traverse through the matrix to identify the rows and + // columns containing zeros and store their indexes in the + // appropriate hash sets. + for r := 0; r < m; r++ { + for c := 0; c < n; c++ { + if matrix[r][c] == 0 { + zeroRows[r] = struct{}{} + zeroCols[c] = struct{}{} + } + } + } + // Pass 2: Set any cell in the matrix to zero if its row index is + // in 'zero_rows' or its column index is in 'zero_cols'. + for r := 0; r < m; r++ { + for c := 0; c < n; c++ { + if _, ok := zeroRows[r]; ok { + matrix[r][c] = 0 + } else if _, ok := zeroCols[c]; ok { + matrix[r][c] = 0 + } + } + } +}