Skip to content

Commit 3bbec04

Browse files
authored
Merge pull request #56 from ineBallardin/go-solutions-hash-maps-and-sets
Go: Chapter 2 Hash Maps and Sets
2 parents 4661f40 + 8f254db commit 3bbec04

8 files changed

+242
-0
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
func geometricSequenceTriplets(nums []int, r int) int {
2+
// Use 'map' to ensure the default value of 0 is returned when
3+
// accessing a key that doesn’t exist in the hash map. This effectively sets
4+
// the default frequency of all elements to 0.
5+
leftMap := make(map[int]int)
6+
rightMap := make(map[int]int)
7+
count := 0
8+
// Populate 'rightMap' with the frequency of each element in the array.
9+
for _, x := range nums {
10+
rightMap[x]++
11+
}
12+
// Search for geometric triplets that have x as the center.
13+
for _, x := range nums {
14+
// Decrement the frequency of x in 'rightMap' since x is now being
15+
// processed and is no longer to the right.
16+
rightMap[x]--
17+
if x%r == 0 {
18+
count += leftMap[x/r] * rightMap[x*r]
19+
}
20+
// Increment the frequency of x in 'leftMap' since it'll be a part of the
21+
// left side of the array once we iterate to the next value of x.
22+
leftMap[x]++
23+
}
24+
return count
25+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
func longestChainOfConsecutiveNumbers(nums []int) int {
2+
if len(nums) == 0 {
3+
return 0
4+
}
5+
numSet := make(map[int]bool)
6+
for _, num := range nums {
7+
numSet[num] = true
8+
}
9+
longestChain := 0
10+
for num := range numSet {
11+
// If the current number is the smallest number in its chain, search for
12+
// the length of its chain.
13+
if !numSet[num-1] {
14+
currentNum := num
15+
currentChain := 1
16+
// Continue to find the next consecutive numbers in the chain.
17+
for numSet[currentNum+1] {
18+
currentNum++
19+
currentChain++
20+
}
21+
if currentChain > longestChain {
22+
longestChain = currentChain
23+
}
24+
}
25+
}
26+
return longestChain
27+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
func longestChainOfConsecutiveNumbersBruteForce(nums []int) int {
2+
if len(nums) == 0 {
3+
return 0
4+
}
5+
longestChain := 0
6+
// Look for chains of consecutive numbers that start from each number.
7+
for _, num := range nums {
8+
currentNum := num
9+
currentChain := 1
10+
// Continue to find the next consecutive numbers in the chain.
11+
for contains(nums, currentNum+1) {
12+
currentNum++
13+
currentChain++
14+
}
15+
if currentChain > longestChain {
16+
longestChain = currentChain
17+
}
18+
}
19+
return longestChain
20+
}
21+
22+
// In the Python code, the while loop checks (current_num +1) in nums.
23+
// So the helper function 'contains' is needed.
24+
func contains(nums []int, target int) bool {
25+
for _, n := range nums {
26+
if n == target {
27+
return true
28+
}
29+
}
30+
return false
31+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
func pairSumUnsorted(nums []int, target int) []int {
2+
hashmap := make(map[int]int)
3+
for i, x := range nums {
4+
complement := target - x
5+
if idx, exists := hashmap[complement]; exists {
6+
return []int{idx, i}
7+
}
8+
hashmap[x] = i
9+
}
10+
return nil
11+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
func pairSumUnsortedTwoPass(nums []int, target int) []int {
2+
numMap := make(map[int]int)
3+
// First pass: Populate the hash map with each number and its index.
4+
for i, num := range nums {
5+
numMap[num] = i
6+
}
7+
// Second pass: Check for each number's complement in the hash map.
8+
for i, num := range nums {
9+
complement := target - num
10+
if idx, ok := numMap[complement]; ok && idx != i {
11+
return []int{i, idx}
12+
}
13+
}
14+
return nil
15+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
func verifySudokuBoard(board [][]int) bool {
2+
// Create hash sets for each row, column, and subgrid to keep
3+
// track of numbers previously seen on any given row, column, or
4+
// subgrid.
5+
rowSets := make([]map[int]struct{}, 9)
6+
columnSets := make([]map[int]struct{}, 9)
7+
subgridSets := make([][]map[int]struct{}, 3)
8+
9+
for i := range rowSets {
10+
rowSets[i] = make(map[int]struct{})
11+
}
12+
for i := range columnSets {
13+
columnSets[i] = make(map[int]struct{})
14+
}
15+
for i := range subgridSets {
16+
subgridSets[i] = make([]map[int]struct{}, 3)
17+
for j := range subgridSets[i] {
18+
subgridSets[i][j] = make(map[int]struct{})
19+
}
20+
}
21+
22+
for r := 0; r < 9; r++ {
23+
for c := 0; c < 9; c++ {
24+
num := board[r][c]
25+
if num == 0 {
26+
continue
27+
}
28+
// Check if 'num' has been seen in the current row,
29+
// column, or subgrid.
30+
if _, exists := rowSets[r][num]; exists {
31+
return false
32+
}
33+
if _, exists := columnSets[c][num]; exists {
34+
return false
35+
}
36+
if _, exists := subgridSets[r/3][c/3][num]; exists {
37+
return false
38+
}
39+
// If we passed the above checks, mark this value as seen
40+
// by adding it to its corresponding hash sets.
41+
rowSets[r][num] = struct{}{}
42+
columnSets[c][num] = struct{}{}
43+
subgridSets[r/3][c/3][num] = struct{}{}
44+
}
45+
}
46+
return true
47+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
func zeroStriping(matrix [][]int) {
2+
if len(matrix) == 0 || len(matrix[0]) == 0 {
3+
return
4+
}
5+
m, n := len(matrix), len(matrix[0])
6+
// Check if the first row initially contains a zero.
7+
firstRowHasZero := false
8+
for c := 0; c < n; c++ {
9+
if matrix[0][c] == 0 {
10+
firstRowHasZero = true
11+
break
12+
}
13+
}
14+
// Check if the first column initially contains a zero.
15+
firstColHasZero := false
16+
for r := 0; r < m; r++ {
17+
if matrix[r][0] == 0 {
18+
firstColHasZero = true
19+
break
20+
}
21+
}
22+
// Use the first row and column as markers. If an element in the
23+
// submatrix is zero, mark its corresponding row and column in the
24+
// first row and column as 0.
25+
for r := 1; r < m; r++ {
26+
for c := 1; c < n; c++ {
27+
if matrix[r][c] == 0 {
28+
matrix[0][c] = 0
29+
matrix[r][0] = 0
30+
}
31+
}
32+
}
33+
// Update the submatrix using the markers in the first row and
34+
// column.
35+
for r := 1; r < m; r++ {
36+
for c := 1; c < n; c++ {
37+
if matrix[0][c] == 0 || matrix[r][0] == 0 {
38+
matrix[r][c] = 0
39+
}
40+
}
41+
}
42+
// If the first row had a zero initially, set all elements in the
43+
// first row to zero.
44+
if firstRowHasZero {
45+
for c := 0; c < n; c++ {
46+
matrix[0][c] = 0
47+
}
48+
}
49+
// If the first column had a zero initially, set all elements in
50+
// the first column to zero.
51+
if firstColHasZero {
52+
for r := 0; r < m; r++ {
53+
matrix[r][0] = 0
54+
}
55+
}
56+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
func zeroStripingHashSets(matrix [][]int) {
2+
if len(matrix) == 0 || len(matrix[0]) == 0 {
3+
return
4+
}
5+
m, n := len(matrix), len(matrix[0])
6+
zeroRows := make(map[int]struct{})
7+
zeroCols := make(map[int]struct{})
8+
// Pass 1: Traverse through the matrix to identify the rows and
9+
// columns containing zeros and store their indexes in the
10+
// appropriate hash sets.
11+
for r := 0; r < m; r++ {
12+
for c := 0; c < n; c++ {
13+
if matrix[r][c] == 0 {
14+
zeroRows[r] = struct{}{}
15+
zeroCols[c] = struct{}{}
16+
}
17+
}
18+
}
19+
// Pass 2: Set any cell in the matrix to zero if its row index is
20+
// in 'zero_rows' or its column index is in 'zero_cols'.
21+
for r := 0; r < m; r++ {
22+
for c := 0; c < n; c++ {
23+
if _, ok := zeroRows[r]; ok {
24+
matrix[r][c] = 0
25+
} else if _, ok := zeroCols[c]; ok {
26+
matrix[r][c] = 0
27+
}
28+
}
29+
}
30+
}

0 commit comments

Comments
 (0)