Golang每日一练(leetDay0029)

简介: Golang每日一练(leetDay0029)

85. 最大矩形 Maximal Rectangle


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

示例 1:

7ff749b7c40068be4013fd8cd9103248.jpeg


输入: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 main
import (
  "fmt"
)
func maximalRectangle(matrix [][]byte) int {
  if len(matrix) == 0 {
    return 0
  }
  rows, cols := len(matrix), len(matrix[0])
  heights := make([]int, cols)
  maxArea := 0
  for 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 := 0
  for i := 0; i <= len(heights); i++ {
    var h int
    if 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 int
      if len(stack) == 0 {
        width = i
      } else {
        width = i - stack[len(stack)-1] - 1
      }
      area := height * width
      if 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 main
import (
  "fmt"
)
func maximalRectangle(matrix [][]byte) int {
  if len(matrix) == 0 {
    return 0
  }
  rows, cols := len(matrix), len(matrix[0])
  heights := make([]int, cols)
  maxArea := 0
  for 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 := 0
  for i := 0; i <= len(heights); i++ {
    var h int
    if 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 int
      if len(stack) == 0 {
        width = i
      } else {
        width = i - stack[len(stack)-1] - 1
      }
      area := height * width
      if 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 main
import (
  "fmt"
)
func maximalRectangle(matrix [][]byte) int {
  if len(matrix) == 0 {
    return 0
  }
  rows, cols := len(matrix), len(matrix[0])
  maxArea := 0
  for 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:

68d81b94bc06cb623f0c80960beb72b2.jpeg




输入: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 main
import (
  "fmt"
)
type ListNode struct {
  Val  int
  Next *ListNode
}
func partition(head *ListNode, x int) *ListNode {
  beforeHead := &ListNode{Val: 0, Next: nil}
  before := beforeHead
  afterHead := &ListNode{Val: 0, Next: nil}
  after := afterHead
  for head != nil {
    if head.Val < x {
      before.Next = head
      before = before.Next
    } else {
      after.Next = head
      after = after.Next
    }
    head = head.Next
  }
  after.Next = nil
  before.Next = afterHead.Next
  return 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.Next
    head.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 main
import (
  "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] = true
            break
          }
        }
      }
    }
  }
  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











目录
相关文章
|
Shell Linux 算法
Shell编程——弱数据类型的脚本语言快速入门指南
Shell编程——弱数据类型的脚本语言快速入门指南
182 0
Shell编程——弱数据类型的脚本语言快速入门指南
|
Go Linux Shell
Linux 终端命令之文件浏览(2) more
Linux 终端命令之文件浏览(2) more
136 0
Linux 终端命令之文件浏览(2) more
|
Shell 机器学习/深度学习 Linux
Linux 终端操作命令(2)内部命令
Linux 终端操作命令(2)内部命令
243 0
Linux 终端操作命令(2)内部命令
|
C++ 算法 存储
力扣 C++|一题多解之动态规划专题(2)
力扣 C++|一题多解之动态规划专题(2)
193 0
力扣 C++|一题多解之动态规划专题(2)
|
Python 索引
Python Numpy入门基础(一)创建数组
Python Numpy入门基础(一)创建数组
225 0
Python Numpy入门基础(一)创建数组
|
Java 容器 程序员
Java语言程序设计试卷6套
Java语言程序设计试卷6套
1120 0
Java语言程序设计试卷6套
|
Java Go C++
Golang每日一练(leetDay0120) 反转字符串中的元音字母、前K个高频元素
Golang每日一练(leetDay0120) 反转字符串中的元音字母、前K个高频元素
188 0
Golang每日一练(leetDay0120) 反转字符串中的元音字母、前K个高频元素
|
Go 机器学习/深度学习 Rust
Golang每日一练(leetDay0119) 反转字符串I\II Reverse String
Golang每日一练(leetDay0119) 反转字符串I\II Reverse String
279 0
Golang每日一练(leetDay0119) 反转字符串I\II Reverse String
|
16天前
|
存储 安全 Java
【Golang】(4)Go里面的指针如何?函数与方法怎么不一样?带你了解Go不同于其他高级语言的语法
结构体可以存储一组不同类型的数据,是一种符合类型。Go抛弃了类与继承,同时也抛弃了构造方法,刻意弱化了面向对象的功能,Go并非是一个传统OOP的语言,但是Go依旧有着OOP的影子,通过结构体和方法也可以模拟出一个类。
68 1
|
Go
Golang语言之管道channel快速入门篇
这篇文章是关于Go语言中管道(channel)的快速入门教程,涵盖了管道的基本使用、有缓冲和无缓冲管道的区别、管道的关闭、遍历、协程和管道的协同工作、单向通道的使用以及select多路复用的详细案例和解释。
522 4
Golang语言之管道channel快速入门篇

热门文章

最新文章

推荐镜像

更多