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 ,执行下述步骤:
- 在一个随机下标处将字符串分割成两个非空的子字符串。即,如果已知字符串
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每日一练 专栏 |