dengxinyi vor 6 Jahren
Ursprung
Commit
3005453340
2 geänderte Dateien mit 134 neuen und 0 gelöschten Zeilen
  1. 91 0
      hard/363.max-sum-of-rectangle-no-larger-than-k.go
  2. 43 0
      hard/391.perfect-rectangle.go

+ 91 - 0
hard/363.max-sum-of-rectangle-no-larger-than-k.go

@@ -0,0 +1,91 @@
+func maxSumSubmatrix(matrix [][]int, k int) (max int) {
+	m := len(matrix)
+	if m == 0 {
+		return 0
+	}
+	n := len(matrix[0])
+	if n == 0 {
+		return 0
+	}
+	// Remember how to calculate the maximum sum of rectangles in a matrix:
+	//
+	// l, r              dp        l    r          dp                      l, r         dp
+	//  -1   -4    0     -1        .   -4   .      -5                   .    .   .       .
+	//   3   -3    4      3  --\   .   -3    .      0  --\   ...  --\   .    .    .      .
+	//   4    8    7      4  --/   .    8     .    12  --/        --/   .    .     .     .
+	//   6   20    1      6        .   20      .   26                   .    .      .    .
+	//
+	// Then, calculate the maximum sum of ranges in 1D array (dp).
+	// Given the target k, the problem is : find the largest sum closest to k in dp.
+	// Time compexity: O(n^2mlog(m)), n < m.
+	max = -1 << 32
+	if m < n { // Ensure n <= m
+		m, n = n, m
+		matrix = transpose(matrix)
+	}
+	for l := 0; l < n; l++ {
+		dp := make([]int, m) // m rows
+		for r := l; r < n; r++ {
+			sum := []int{0}
+			currSum := 0
+			for i := 0; i < m; i++ {
+				dp[i] += matrix[i][r]
+				currSum += dp[i]
+				idx := lower_bound(sum, currSum-k)
+				if idx != len(sum) {
+					max = maxInt(max, currSum-sum[idx])
+				}
+				insert(&sum, currSum)
+			}
+		}
+	}
+	return
+}
+
+func maxInt(x, y int) int {
+	if x < y {
+		return y
+	}
+	return x
+}
+
+func transpose(matrix [][]int) [][]int {
+	m, n := len(matrix), len(matrix[0])
+	res := make([][]int, n)
+	for i := 0; i < n; i++ {
+		res[i] = make([]int, m)
+		for j := 0; j < m; j++ {
+			res[i][j] = matrix[j][i]
+		}
+	}
+	return res
+}
+
+func lower_bound(nums []int, val int) int {
+	beg, end := 0, len(nums)-1
+	for beg <= end {
+		mid := beg + (end-beg)/2
+		if nums[mid] < val {
+			beg = mid + 1
+		} else if val < nums[mid] {
+			end = mid - 1
+		} else {
+			return mid
+		}
+	}
+	return beg
+}
+
+func insert(nums *[]int, val int) { // nums is a set.
+	i := lower_bound(*nums, val)
+	if n := len(*nums); i == n {
+		*nums = append(*nums, val)
+	} else if (*nums)[i] != val {
+		newNums := make([]int, n+1)
+		copy(newNums, (*nums)[:i])
+		newNums[i] = val
+		copy(newNums[i+1:], (*nums)[i:])
+		*nums = newNums
+	}
+}
+

+ 43 - 0
hard/391.perfect-rectangle.go

@@ -0,0 +1,43 @@
+type pair struct {
+	_1 int
+	_2 int
+}
+
+func isRectangleCover(rectangles [][]int) bool {
+	w, a, s, d := rectangles[0][3], rectangles[0][0], rectangles[0][1], rectangles[0][2]
+	area := 0
+	m := make(map[pair]bool)
+	for i := range rectangles {
+		cw, ca, cs, cd := rectangles[i][3], rectangles[i][0], rectangles[i][1], rectangles[i][2]
+		w, a, s, d = maxInt(w, cw), minInt(a, ca), minInt(s, cs), maxInt(d, cd) // Record the max rectangle
+		area += (cw - cs) * (cd - ca)
+		put(&m, ca, cw) // If the coverage is perfect, all points appear in pair except tl, tr, bl and br.
+		put(&m, cd, cw)
+		put(&m, ca, cs)
+		put(&m, cd, cs)
+	}
+	return m[pair{a, w}] && m[pair{d, w}] && m[pair{a, s}] && m[pair{d, s}] && len(m) == 4 && area == (w-s)*(d-a)
+}
+
+func put(m *map[pair]bool, x, y int) {
+	p := pair{x, y}
+	if _, ok := (*m)[p]; ok {
+		delete(*m, p)
+	} else {
+		(*m)[p] = true
+	}
+}
+
+func maxInt(x, y int) int {
+	if x < y {
+		return y
+	}
+	return x
+}
+
+func minInt(x, y int) int {
+	if x < y {
+		return x
+	}
+	return y
+}