q54 spiral matrix
Problem solution
Traverse each row and column layer by layer. The last element of each row or column is the beginning of the next column or row. Because the side length of the matrix in the topic is not necessarily equal, there will be one more row or column in the end, which can be handled separately.
func spiralOrder(matrix [][]int) []int { if len(matrix) == 0 { return []int{} } res := make([]int, 0) top, bottom, left, right := 0, len(matrix) - 1, 0, len(matrix[0]) - 1 // The last element of each row or column is the beginning of the next column or row for top < bottom && left < right { for i := left; i < right; i++ { res = append(res, matrix[top][i]) } for i := top; i < bottom; i++ { res = append(res, matrix[i][right]) } for i := right; i > left; i-- { res = append(res, matrix[bottom][i]) } for i := bottom; i > top; i-- { res = append(res, matrix[i][left]) } right-- top++ bottom-- left++ } // One more line if top == bottom { for i := left; i <= right; i++ { res = append(res, matrix[top][i]) } // One more column } else if left == right { for i := top; i <= bottom; i++ { res = append(res, matrix[i][left]) } } return res }
q73 matrix zeroing
Problem solution
Use a hash table to mark the coordinates with the value of 0, and then traverse the hash table to set the elements of the same row and column to 0.
type Point struct { x int y int } func setZeroes(matrix [][]int) { m, n := len(matrix), len(matrix[0]) hashTable := make(map[Point]bool) for i := 0; i < m; i++ { for j := 0; j < n; j++ { if matrix[i][j] == 0 && hashTable[Point{i, j}] == false { hashTable[Point{i, j}] = true } } } for key, _ := range hashTable { // The same column becomes 0 for i := 0; i < m; i++ { matrix[i][key.y] = 0 } // Peer changes to 0 for i := 0; i < n; i++ { matrix[key.x][i] = 0 } } }
q78 subset
Problem solution
This problem can be solved by two methods: dfs and bfs.
dfs:
func subsets(nums []int) [][]int { res = make([][]int, 0) dfs(nums, 0, nil) return res } func dfs(nums []int, path int, prefix []int) { if path >= len(nums) { dst := make([]int, len(prefix)) copy(dst, prefix) res = append(res, dst) return } dfs(nums, path + 1, append(prefix, nums[path])) dfs(nums, path + 1, prefix) }
bfs:
func subsets1(nums []int) [][]int { res := make([][]int, 0) path := make([]int, 0) var bfs func(int) bfs = func(start int) { if start > len(nums) { return } tmp := make([]int, len(path)) copy(tmp, path) res = append(res, tmp) for i := start; i < len(nums); i++ { path = append(path, nums[i]) bfs(i + 1) path = path[:len(path) - 1] } } bfs(0) return res }
q384 scramble array
Problem solution
The hardest part of this problem is how to disrupt the array. The strategy is as follows: cycle n times, and exchange the randomly obtained array element with the last element of the array each time.
type Solution struct { nums []int reNums []int } func Constructor(nums []int) Solution { return Solution{nums: nums, reNums: append([]int{}, nums...)} } func (this *Solution) Reset() []int { return this.reNums } func (this *Solution) Shuffle() []int { for n := len(this.nums); n > 0; n-- { randIndex := rand2.Intn(n) this.nums[n - 1], this.nums[randIndex] = this.nums[randIndex], this.nums[n - 1] } return this.nums }
q581 shortest continuous unordered subarray
Problem solution
First, we need to determine the boundary of the subarray. We set it as begin and end. In fact, begin is the subscript of the last number larger than the minimum value, while end is actually the subscript of the last element smaller than the maximum value. For example, it is easy to understand: {1, 2, 5, 4, 3, 6, 7}. In this example, the last number smaller than the maximum value is actually 3. When the array traverses to 3, the maximum value at this time is 5, so 3 is the last number smaller than the maximum value. In subsequent traversals, the maximum value is updated. Then the same is true for finding the left boundary.
func findUnsortedSubarray(nums []int) int { n := len(nums) min, max := nums[n - 1], nums[0] begin, end := -1, -1 for i := 0; i < n; i++ { if nums[i] >= max { max = nums[i] } else { end = i } if nums[n - i - 1] <= min { min = nums[n - i - 1] } else { begin = n - i - 1 } } // Special judgment if end == -1 { return 0 } return end - begin + 1 }
q945 uses the smallest increment unique to the array
Problem solution
First sort the array, and then traverse the array. If the current element is less than or equal to its previous element, it will become the previous number + 1.
func minIncrementForUnique(nums []int) int { sort.Ints(nums) move := 0 for i := 1; i < len(nums); i++ { if nums[i] <= nums[i - 1] { prev := nums[i] nums[i] = nums[i - 1] + 1 move += nums[i] - prev } } return move }