> 文章列表 > Golang每日一练(leetDay0029)

Golang每日一练(leetDay0029)

Golang每日一练(leetDay0029)

 

目录

85. 最大矩形 Maximal Rectangle  🌟🌟🌟

86. 分隔链表 Partition List  🌟🌟

87. 扰乱字符串 Scramble String  🌟🌟🌟

🌟 每日一练刷题专栏 🌟

Golang每日一练 专栏

Python每日一练 专栏

C/C++每日一练 专栏

Java每日一练 专栏


85. 最大矩形 Maximal Rectangle

给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。

示例 1:

输入:matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]
输出:6
解释:最大矩形如上图所示。

示例 2:

输入:matrix = []
输出:0

示例 3:

输入:matrix = [["0"]]
输出:0

示例 4:

输入:matrix = [["1"]]
输出:1

示例 5:

输入:matrix = [["0","0"]]
输出:0

提示:

  • rows == matrix.length
  • cols == matrix[0].length
  • 1 <= row, cols <= 200
  • matrix[i][j] 为 '0' 或 '1'

 代码1: 动态规划

package mainimport ("fmt"
)func maximalRectangle(matrix [][]byte) int {if len(matrix) == 0 {return 0}rows, cols := len(matrix), len(matrix[0])heights := make([]int, cols)maxArea := 0for i := 0; i < rows; i++ {for j := 0; j < cols; j++ {if matrix[i][j] == '1' {heights[j]++} else {heights[j] = 0}}area := largestRectangleArea(heights)if area > maxArea {maxArea = area}}return maxArea
}func largestRectangleArea(heights []int) int {stack := make([]int, 0)maxArea := 0for i := 0; i <= len(heights); i++ {var h intif i == len(heights) {h = 0} else {h = heights[i]}for len(stack) > 0 && h < heights[stack[len(stack)-1]] {height := heights[stack[len(stack)-1]]stack = stack[:len(stack)-1]var width intif len(stack) == 0 {width = i} else {width = i - stack[len(stack)-1] - 1}area := height * widthif area > maxArea {maxArea = area}}stack = append(stack, i)}return maxArea
}func main() {matrix := [][]byte{{'1', '0', '1', '0', '0'},{'1', '0', '1', '1', '1'},{'1', '1', '1', '1', '1'},{'1', '0', '0', '1', '0'}}fmt.Println(maximalRectangle(matrix))
}

 代码2: 栈

package mainimport ("fmt"
)func maximalRectangle(matrix [][]byte) int {if len(matrix) == 0 {return 0}rows, cols := len(matrix), len(matrix[0])heights := make([]int, cols)maxArea := 0for i := 0; i < rows; i++ {for j := 0; j < cols; j++ {if matrix[i][j] == '1' {heights[j]++} else {heights[j] = 0}}area := largestRectangleArea(heights)if area > maxArea {maxArea = area}}return maxArea
}func largestRectangleArea(heights []int) int {stack := make([]int, 0)maxArea := 0for i := 0; i <= len(heights); i++ {var h intif i == len(heights) {h = 0} else {h = heights[i]}for len(stack) > 0 && h < heights[stack[len(stack)-1]] {height := heights[stack[len(stack)-1]]stack = stack[:len(stack)-1]var width intif len(stack) == 0 {width = i} else {width = i - stack[len(stack)-1] - 1}area := height * widthif area > maxArea {maxArea = area}}stack = append(stack, i)}return maxArea
}func main() {matrix := [][]byte{{'1', '0', '1', '0', '0'},{'1', '0', '1', '1', '1'},{'1', '1', '1', '1', '1'},{'1', '0', '0', '1', '0'}}fmt.Println(maximalRectangle(matrix))
}

 代码3: 暴力枚举

package mainimport ("fmt"
)func maximalRectangle(matrix [][]byte) int {if len(matrix) == 0 {return 0}rows, cols := len(matrix), len(matrix[0])maxArea := 0for i := 0; i < rows; i++ {for j := 0; j < cols; j++ {if matrix[i][j] == '1' {for k := i; k < rows; k++ {for l := j; l < cols; l++ {if isRectangle(matrix, i, j, k, l) {area := (k - i + 1) * (l - j + 1)if area > maxArea {maxArea = area}}}}}}}return maxArea
}func isRectangle(matrix [][]byte, i, j, k, l int) bool {for m := i; m <= k; m++ {for n := j; n <= l; n++ {if matrix[m][n] == '0' {return false}}}return true
}func main() {matrix := [][]byte{{'1', '0', '1', '0', '0'},{'1', '0', '1', '1', '1'},{'1', '1', '1', '1', '1'},{'1', '0', '0', '1', '0'}}fmt.Println(maximalRectangle(matrix))
}

输出:

6


86. 分隔链表 Partition List

给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。

你应当 保留 两个分区中每个节点的初始相对位置。

示例 1:

输入:head = [1,4,3,2,5,2], x = 3
输出:[1,2,2,4,3,5]

示例 2:

输入:head = [2,1], x = 2
输出:[1,2]

提示:

  • 链表中节点的数目在范围 [0, 200] 内
  • -100 <= Node.val <= 100
  • -200 <= x <= 200

代码:

package mainimport ("fmt"
)type ListNode struct {Val  intNext *ListNode
}func partition(head *ListNode, x int) *ListNode {beforeHead := &ListNode{Val: 0, Next: nil}before := beforeHeadafterHead := &ListNode{Val: 0, Next: nil}after := afterHeadfor head != nil {if head.Val < x {before.Next = headbefore = before.Next} else {after.Next = headafter = after.Next}head = head.Next}after.Next = nilbefore.Next = afterHead.Nextreturn beforeHead.Next
}func build(list []int) *ListNode {head := &ListNode{Val: 0}for i := len(list) - 1; i >= 0; i-- {p := &ListNode{Val: list[i]}p.Next = head.Nexthead.Next = p}return head
}func (head *ListNode) travel() {for p := head.Next; p != nil; p = p.Next {fmt.Print(p.Val)if p.Next != nil {fmt.Print("->")}}fmt.Println("<nil>")
}func main() {nums := []int{1, 4, 3, 2, 5, 2}head := build(nums)head.travel()partition(head, 3).travel()nums = []int{2, 1}head = build(nums)head.travel()partition(head, 2).travel()
}

输出:

1->4->3->2->5->2<nil>
1->2->2->4->3->5<nil>
2->1<nil>
1->2<nil>


87. 扰乱字符串 Scramble String

使用下面描述的算法可以扰乱字符串 s 得到字符串 t :

  1. 如果字符串的长度为 1 ,算法停止
  2. 如果字符串的长度 > 1 ,执行下述步骤:
    • 在一个随机下标处将字符串分割成两个非空的子字符串。即,如果已知字符串 s ,则可以将其分成两个子字符串 x 和 y ,且满足 s = x + y 。
    • 随机 决定是要「交换两个子字符串」还是要「保持这两个子字符串的顺序不变」。即,在执行这一步骤之后,s 可能是 s = x + y 或者 s = y + x 。
    • 在 x 和 y 这两个子字符串上继续从步骤 1 开始递归执行此算法。

给你两个 长度相等 的字符串 s1 和 s2,判断 s2 是否是 s1 的扰乱字符串。如果是,返回 true ;否则,返回 false 。

示例 1:

输入:s1 = "great", s2 = "rgeat"
输出:true
解释:s1 上可能发生的一种情形是:
"great" --> "gr/eat" // 在一个随机下标处分割得到两个子字符串
"gr/eat" --> "gr/eat" // 随机决定:「保持这两个子字符串的顺序不变」
"gr/eat" --> "g/r / e/at" // 在子字符串上递归执行此算法。两个子字符串分别在随机下标处进行一轮分割
"g/r / e/at" --> "r/g / e/at" // 随机决定:第一组「交换两个子字符串」,第二组「保持这两个子字符串的顺序不变」
"r/g / e/at" --> "r/g / e/ a/t" // 继续递归执行此算法,将 "at" 分割得到 "a/t"
"r/g / e/ a/t" --> "r/g / e/ a/t" // 随机决定:「保持这两个子字符串的顺序不变」
算法终止,结果字符串和 s2 相同,都是 "rgeat"
这是一种能够扰乱 s1 得到 s2 的情形,可以认为 s2 是 s1 的扰乱字符串,返回 true

示例 2:

输入:s1 = "abcde", s2 = "caebd"
输出:false

示例 3:

输入:s1 = "a", s2 = "a"
输出:true

提示:

  • s1.length == s2.length
  • 1 <= s1.length <= 30
  • s1 和 s2 由小写英文字母组成

代码:

package mainimport ("fmt"
)func isScramble(s1 string, s2 string) bool {if s1 == s2 {return true}if len(s1) != len(s2) {return false}size := len(s1)dp := make([][][]bool, size)for i := 0; i < size; i++ {dp[i] = make([][]bool, size)for j := 0; j < size; j++ {dp[i][j] = make([]bool, size+1)dp[i][j][1] = s1[i] == s2[j]}}for l := 2; l <= size; l++ {for i := 0; i <= size-l; i++ {for j := 0; j <= size-l; j++ {for k := 1; k < l; k++ {if (dp[i][j][k] && dp[i+k][j+k][l-k]) || (dp[i][j+l-k][k] && dp[i+k][j][l-k]) {dp[i][j][l] = truebreak}}}}}return dp[0][0][size]
}func main() {s1 := "great"s2 := "rgeat"fmt.Println(isScramble(s1, s2))s1 = "abcde"s2 = "caebd"fmt.Println(isScramble(s1, s2))
}

输出:

true
false


🌟 每日一练刷题专栏 🌟

持续,努力奋斗做强刷题搬运工!

👍 点赞,你的认可是我坚持的动力! 

🌟 收藏,你的青睐是我努力的方向! 

评论,你的意见是我进步的财富!  

 主页:https://hannyang.blog.csdn.net/ 

Golang每日一练 专栏

Python每日一练 专栏

C/C++每日一练 专栏

Java每日一练 专栏