Golang每日一练(leetDay0044) 被围绕的区域、分割回文串I\II

简介: Golang每日一练(leetDay0044) 被围绕的区域、分割回文串I\II

130. 被围绕的区域 Surrounded Regions

给你一个 m x n 的矩阵 board ,由若干字符 'X''O' ,找到所有被 'X' 围绕的区域,并将这些区域里所有的 'O''X' 填充。

示例 1:

输入:board = [["X","X","X","X"],["X","O","O","X"],["X","X","O","X"],["X","O","X","X"]]

输出:[["X","X","X","X"],["X","X","X","X"],["X","X","X","X"],["X","O","X","X"]]

解释:被围绕的区间不会存在于边界上,换句话说,任何边界上的 'O' 都不会被填充为 'X'。 任何不在边界上,或不与边界上的 'O' 相连的 'O' 最终都会被填充为 'X'。如果两个元素在水平或垂直方向相邻,则称它们是“相连”的。


示例 2:

输入:board = [["X"]]

输出:[["X"]]


提示:

  • m == board.length
  • n == board[i].length
  • 1 <= m, n <= 200
  • board[i][j]'X''O'

代码1:DFS

package main
import (
  "fmt"
)
func solve(board [][]byte) {
  if len(board) == 0 || len(board[0]) == 0 {
    return
  }
  m, n := len(board), len(board[0])
  // 从边界的'O'出发,将与其相连的'O'标记为'A'
  for i := 0; i < m; i++ {
    dfs(board, i, 0)
    dfs(board, i, n-1)
  }
  for j := 0; j < n; j++ {
    dfs(board, 0, j)
    dfs(board, m-1, j)
  }
  // 将未被标记的'O'填充为'X',将标记为'A'的'O'恢复为'O'
  for i := 0; i < m; i++ {
    for j := 0; j < n; j++ {
      if board[i][j] == 'O' {
        board[i][j] = 'X'
      } else if board[i][j] == 'A' {
        board[i][j] = 'O'
      }
    }
  }
}
func dfs(board [][]byte, i, j int) {
  if i < 0 || i >= len(board) || j < 0 || j >= len(board[0]) || board[i][j] != 'O' {
    return
  }
  board[i][j] = 'A'
  dfs(board, i-1, j)
  dfs(board, i+1, j)
  dfs(board, i, j-1)
  dfs(board, i, j+1)
}
func ArrayToString(arr []byte) string {
  res := "["
  for i := 0; i < len(arr); i++ {
    res += string(arr[i])
    if i != len(arr)-1 {
      res += ","
    }
  }
  return res + "]"
}
func main() {
  board := [][]byte{
    {'X', 'X', 'X', 'X'},
    {'X', 'O', 'O', 'X'},
    {'X', 'X', 'O', 'X'},
    {'X', 'O', 'X', 'X'}}
  solve(board)
  for _, row := range board {
    fmt.Println(ArrayToString(row))
  }
}

输出:

[X,X,X,X]

[X,X,X,X]

[X,X,X,X]

[X,O,X,X]

代码2: BFS

package main
import (
  "fmt"
)
func solve(board [][]byte) {
  if len(board) == 0 || len(board[0]) == 0 {
    return
  }
  m, n := len(board), len(board[0])
  // 从边界的'O'出发,将与其相连的'O'标记为'A'
  queue := make([][2]int, 0)
  for i := 0; i < m; i++ {
    if board[i][0] == 'O' {
      queue = append(queue, [2]int{i, 0})
    }
    if board[i][n-1] == 'O' {
      queue = append(queue, [2]int{i, n - 1})
    }
  }
  for j := 0; j < n; j++ {
    if board[0][j] == 'O' {
      queue = append(queue, [2]int{0, j})
    }
    if board[m-1][j] == 'O' {
      queue = append(queue, [2]int{m - 1, j})
    }
  }
  for len(queue) > 0 {
    i, j := queue[0][0], queue[0][1]
    queue = queue[1:]
    board[i][j] = 'A'
    if i > 0 && board[i-1][j] == 'O' {
      queue = append(queue, [2]int{i - 1, j})
    }
    if i < m-1 && board[i+1][j] == 'O' {
      queue = append(queue, [2]int{i + 1, j})
    }
    if j > 0 && board[i][j-1] == 'O' {
      queue = append(queue, [2]int{i, j - 1})
    }
    if j < n-1 && board[i][j+1] == 'O' {
      queue = append(queue, [2]int{i, j + 1})
    }
  }
  // 将未被标记的'O'填充为'X',将标记为'A'的'O'恢复为'O'
  for i := 0; i < m; i++ {
    for j := 0; j < n; j++ {
      if board[i][j] == 'O' {
        board[i][j] = 'X'
      } else if board[i][j] == 'A' {
        board[i][j] = 'O'
      }
    }
  }
}
func ArrayToString(arr []byte) string {
  res := "["
  for i := 0; i < len(arr); i++ {
    res += string(arr[i])
    if i != len(arr)-1 {
      res += ","
    }
  }
  return res + "]"
}
func main() {
  board := [][]byte{
    {'X', 'X', 'X', 'X'},
    {'X', 'O', 'O', 'X'},
    {'X', 'X', 'O', 'X'},
    {'X', 'O', 'X', 'X'}}
  solve(board)
  for _, row := range board {
    fmt.Println(ArrayToString(row))
  }
}

131. 分割回文串 Palindrome Partitioning

给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。

回文串 是正着读和反着读都一样的字符串。

示例 1:

输入:s = "aab"

输出:[["a","a","b"],["aa","b"]]


示例 2:

输入:s = "a"

输出:[["a"]]


提示:

  • 1 <= s.length <= 16
  • s 仅由小写英文字母组成

代码1: 动态规划

package main
import (
  "fmt"
  "strings"
)
func partition(s string) [][]string {
  n := len(s)
  dp := make([][]bool, n)
  for i := range dp {
    dp[i] = make([]bool, n)
  }
  for j := 0; j < n; j++ {
    for i := 0; i <= j; i++ {
      if s[i] == s[j] && (j-i <= 2 || dp[i+1][j-1]) {
        dp[i][j] = true
      }
    }
  }
  res := make([][]string, 0)
  path := make([]string, 0)
  dfs(s, 0, dp, path, &res)
  return res
}
func dfs(s string, start int, dp [][]bool, path []string, res *[][]string) {
  if start == len(s) {
    tmp := make([]string, len(path))
    copy(tmp, path)
    *res = append(*res, tmp)
    return
  }
  for i := start; i < len(s); i++ {
    if dp[start][i] {
      path = append(path, s[start:i+1])
      dfs(s, i+1, dp, path, res)
      path = path[:len(path)-1]
    }
  }
}
func ArrayToString(arr []string) string {
  res := "["
  for i := 0; i < len(arr); i++ {
    res += arr[i]
    if i != len(arr)-1 {
      res += ","
    }
  }
  return res + "]"
}
func main() {
  str := "aab"
  fmt.Println(strings.Join(strings.Fields(fmt.Sprint(partition(str))), ","))
  str = "a"
  fmt.Println(strings.Join(strings.Fields(fmt.Sprint(partition(str))), ","))
}

输出:

[[a,a,b],[aa,b]]

[[a]]

代码2: 回溯

package main
import (
  "fmt"
  "strings"
)
func partition(s string) [][]string {
  res := make([][]string, 0)
  path := make([]string, 0)
  backtrack(s, 0, path, &res)
  return res
}
func backtrack(s string, start int, path []string, res *[][]string) {
  if start == len(s) {
    tmp := make([]string, len(path))
    copy(tmp, path)
    *res = append(*res, tmp)
    return
  }
  for i := start; i < len(s); i++ {
    if isPalindrome(s, start, i) {
      path = append(path, s[start:i+1])
      backtrack(s, i+1, path, res)
      path = path[:len(path)-1]
    }
  }
}
func isPalindrome(s string, start, end int) bool {
  for start < end {
    if s[start] != s[end] {
      return false
    }
    start++
    end--
  }
  return true
}
func ArrayToString(arr []string) string {
  res := "["
  for i := 0; i < len(arr); i++ {
    res += arr[i]
    if i != len(arr)-1 {
      res += ","
    }
  }
  return res + "]"
}
func main() {
  str := "aab"
  fmt.Println(strings.Join(strings.Fields(fmt.Sprint(partition(str))), ","))
  str = "a"
  fmt.Println(strings.Join(strings.Fields(fmt.Sprint(partition(str))), ","))
}

132. 分割回文串 II Palindrome Partitioning II

给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是回文。

返回符合要求的 最少分割次数

示例 1:

输入:s = "aab"

输出:1

解释:只需一次分割就可将 s 分割成 ["aa","b"] 这样两个回文子串。


示例 2:

输入:s = "a"

输出:0


示例 3:

输入:s = "ab"

输出:1


提示:

  • 1 <= s.length <= 2000
  • s 仅由小写英文字母组成

代码1: 动态规划

package main
import (
  "fmt"
)
func minCut(s string) int {
  n := len(s)
  dp := make([][]bool, n)
  for i := range dp {
    dp[i] = make([]bool, n)
  }
  for j := 0; j < n; j++ {
    for i := 0; i <= j; i++ {
      if s[i] == s[j] && (j-i <= 2 || dp[i+1][j-1]) {
        dp[i][j] = true
      }
    }
  }
  cut := make([]int, n)
  for i := 0; i < n; i++ {
    if dp[0][i] {
      cut[i] = 0
      continue
    }
    cut[i] = i
    for j := 0; j < i; j++ {
      if dp[j+1][i] {
        cut[i] = min(cut[i], cut[j]+1)
      }
    }
  }
  return cut[n-1]
}
func min(a, b int) int {
  if a < b {
    return a
  }
  return b
}
func main() {
  str := "aab"
  fmt.Println(minCut(str))
  str = "a"
  fmt.Println(minCut(str))
  str = "ab"
  fmt.Println(minCut(str))
}

输出:

1

0

1

代码2: 动态规划

package main
import (
  "fmt"
)
func minCut(s string) int {
  n := len(s)
  cut := make([]int, n)
  for i := range cut {
    cut[i] = i
  }
  for i := 0; i < n; i++ {
    expand(s, i, i, &cut)
    expand(s, i, i+1, &cut)
  }
  return cut[n-1]
}
func expand(s string, left, right int, cut *[]int) {
  for left >= 0 && right < len(s) && s[left] == s[right] {
    if left == 0 {
      (*cut)[right] = 0
    } else {
      (*cut)[right] = min((*cut)[right], (*cut)[left-1]+1)
    }
    left--
    right++
  }
}
func min(a, b int) int {
  if a < b {
    return a
  }
  return b
}
func main() {
  str := "aab"
  fmt.Println(minCut(str))
  str = "a"
  fmt.Println(minCut(str))
  str = "ab"
  fmt.Println(minCut(str))
}

🌟 每日一练刷题专栏 🌟

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

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

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

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

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


目录
相关文章
|
6天前
|
Python 人工智能
讯飞星火、文心一言和通义千问同时编“贪吃蛇”游戏,谁会胜出?
讯飞星火、文心一言和通义千问同时编“贪吃蛇”游戏,谁会胜出?
53 1
讯飞星火、文心一言和通义千问同时编“贪吃蛇”游戏,谁会胜出?
|
6天前
|
Shell Linux 算法
Shell编程——弱数据类型的脚本语言快速入门指南
Shell编程——弱数据类型的脚本语言快速入门指南
58 0
Shell编程——弱数据类型的脚本语言快速入门指南
|
6天前
|
Shell Unix Linux
Linux 终端命令之文件浏览(3) less
Linux 终端命令之文件浏览(3) less
34 0
Linux 终端命令之文件浏览(3) less
|
6天前
|
Go Linux Shell
Linux 终端命令之文件浏览(2) more
Linux 终端命令之文件浏览(2) more
34 0
Linux 终端命令之文件浏览(2) more
|
6天前
|
Rust
Rust 编程小技巧摘选(8)
Rust 编程小技巧摘选(8)
99 0
Rust 编程小技巧摘选(8)
|
6天前
|
Shell 机器学习/深度学习 Linux
Linux 终端操作命令(2)内部命令
Linux 终端操作命令(2)内部命令
25 0
Linux 终端操作命令(2)内部命令
|
6天前
|
算法 C++ 机器人
力扣 C++|一题多解之动态规划专题(1)
力扣 C++|一题多解之动态规划专题(1)
43 0
力扣 C++|一题多解之动态规划专题(1)
|
6天前
|
C++ 算法 存储
力扣 C++|一题多解之动态规划专题(2)
力扣 C++|一题多解之动态规划专题(2)
40 0
力扣 C++|一题多解之动态规划专题(2)
|
6天前
|
监控 算法 Go
Golang深入浅出之-Go语言中的服务熔断、降级与限流策略
【5月更文挑战第4天】本文探讨了分布式系统中保障稳定性的重要策略:服务熔断、降级和限流。服务熔断通过快速失败和暂停故障服务调用来保护系统;服务降级在压力大时提供有限功能以保持整体可用性;限流控制访问频率,防止过载。文中列举了常见问题、解决方案,并提供了Go语言实现示例。合理应用这些策略能增强系统韧性和可用性。
56 0
|
6天前
|
分布式计算 Java Go
Golang深入浅出之-Go语言中的分布式计算框架Apache Beam
【5月更文挑战第6天】Apache Beam是一个统一的编程模型,适用于批处理和流处理,主要支持Java和Python,但也提供实验性的Go SDK。Go SDK的基本概念包括`PTransform`、`PCollection`和`Pipeline`。在使用中,需注意类型转换、窗口和触发器配置、资源管理和错误处理。尽管Go SDK文档有限,生态系统尚不成熟,且性能可能不高,但它仍为分布式计算提供了可移植的解决方案。通过理解和掌握Beam模型,开发者能编写高效的数据处理程序。
142 1