美文网首页
palindrome-partitioning分割成回文串 go

palindrome-partitioning分割成回文串 go

作者: fjxCode | 来源:发表于2018-09-22 15:22 被阅读0次

palindrome-partitioning分割成回文串

题目:

Given a string s, partition s such that every substring of the partition is a palindrome.
Return all possible palindrome partitioning of s.
For example, given s ="aab",
Return
  [
    ["aa","b"],
    ["a","a","b"]
  ] 

思路:

  • 一般找出所有解使用DFS,最优解用动态规划。
  • 用递归解,用动规和回溯算法也能解。
  • 树的含义。子节点为切一段子串的,所有切法。对于是回文串的继续递归子问题求解。
  • “回文的判定”如同“节点是否遍历过的判定”。解为遍历到根节点(空串)的“路径”。
  • 算法形如dfs,dfs算法复杂度和bfs相同,用邻接矩阵为O(n^2),用邻接点数组O(e)。
  • 对于go,切片是传值的。如果切片不加指针,res无法积累结果。
  • collect可以用值拷贝,方便加入集合res。但最好用引用拷贝提高效率,再加入集合前使用前拷贝copy()复制。

细节:

  • 切片是不定长数组,可以当链表集合保存结果,不必使用标准库链表。

  • 会用二维切片初始化和二维数组初始化。对于用数组还是用切片的选取。

  • 声明变量var name必须初始化赋值,var name string可以只声明。

  • 用切片代替链表集合。切片直接初始化,或者直接赋指针,不需要make。作集合用时,可以直接赋指针,也可以选取部分元素slice[m:n]。一般不用copy前拷贝。

  • go不允许将最终return放在最终if中。

  • go不允许书写str[idx++] = sp的形式。

    //二维切片初始化。第二维make初始化指定了长度,所以可以用赋值,第一维没有make(),不能用x[i] = str。
    f := make([][]int, n)
    for i := 0; i < len(matrix); i++ {
    f[i] = make([]int, n)
    //注意思有类型推演符:
    }
    //第一次make变量未初始化,有推演符:,第2次变量make已初始化,无推演符。
    //二维数组声明var array [n][n]int。由于是值拷贝,不能传址。
    //二维数组初始化var array [2][2]int = [2][2]int{{0,1},{0,1}}

//二维切片作集合时,直接赋值,不make
//make切片必须指定长度,这个可以理解,ArrayList也是有初始大小的,go把权力交给了程序员以避免开销。
    var strings [][]string
    str := []string{"a", "b", "c"}
    strings[0] = str



//传值的切片,导致无法拷贝结果
func dfs(s string, collect *[]string, res [][]string) {
    if s == "" {
        //error code
        fmt.Println(collect)
        res = append(res, *collect)
        fmt.Print("res is")
        for _,elem := range res {
            fmt.Print(elem)
        }
        //到达叶节点,递归返回
        return
    }
}

所以,结果res是传址的,负责方法内外的沟通。collect要是传值的,由于collect通过调用append映射到res,传址的collect更新后,不仅新加入的collect值会变,原来已加入的Collect也会改变。简之,集合添加元素用值拷贝。

解(递归时,collect为值拷贝):

//注释的代码用于测试
package main

import "fmt"

func partition(s string) [][]string {
    var res [][]string
    var collect []string
    dfs(s, collect, &res)
    return res
}

func dfs(s string, collect []string, res *[][]string) {
    if s == "" {
        //tip
        //fmt.Println(collect)
        *res = append(*res, collect)
        //fmt.Print("res is")
        //for _,elem := range *res {
        //  fmt.Print(elem)
        //}
        //到达叶节点,递归返回
        return
    }
    for i := 1; i <= len(s); i++ {
        child := s[0:i]
        if isPalindrome(child) {
            collect = append(collect, child)
            dfs(s[i:], collect, res)
            //递归完成剩余子树,要恢复状态
            //取指针优先于索引下标
            collect = (collect)[0 : len(collect)-1]
        }
    }

}

func isPalindrome(s string) bool {
    len := len(s)
    for i := 0; i < len/2; i++ {
        //字串可以直接[],不需要避免charAt()
        if s[i] != s[len-1-i] {
            return false
        }
    }
    return true
}

func main() {
    str := "aab"
    res := partition(str)
    for _,elem := range res {
        fmt.Print(elem)
    }
}

解(在递归中collect引用传递):

package main

import "fmt"

func partition(s string) [][]string {
    var res [][]string
    var collect []string
    dfs(s, &collect, &res)
    return res
}

func dfs(s string, collect *[]string, res *[][]string) {
    if s == "" {
        //error code
        collected := make([]string,len(*collect))
        copy(collected,*collect)
        *res = append(*res, collected)
        //到达叶节点,递归返回
        return
    }
    for i := 1; i <= len(s); i++ {
        child := s[0:i]
        if isPalindrome(child) {
            *collect = append(*collect, child)
            dfs(s[i:], collect, res)
            //递归完成剩余子树,要恢复状态
            //取指针优先于索引下标
            *collect = (*collect)[0 : len(*collect)-1]
        }
    }

}

func isPalindrome(s string) bool {
    len := len(s)
    for i := 0; i < len/2; i++ {
        //字串可以直接[],不需要避免charAt()
        if s[i] != s[len-1-i] {
            return false
        }
    }
    return true
}

func main() {
    str := "aab"
    res := partition(str)
    for _,elem := range res {
        fmt.Print(elem)
    }
}

相关文章

  • palindrome-partitioning分割成回文串 go

    palindrome-partitioning分割成回文串 题目: 思路: 一般找出所有解使用DFS,最优解用动态...

  • lintcode-分割回文串

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

  • 131. 分割回文串

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

  • LeetCode-131-分割回文串

    分割回文串 题目描述:给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能...

  • Go语言:字符串数组 拼接成 字符串

    代码实例: 相关文章: Go语言:字符串数组 拼接成 字符串 Go语言:字符串 分割成 字符串数组

  • Go语言:字符串 分割成 字符串数组

    代码实例: 相关文章: Go语言:字符串数组 拼接成 字符串 Go语言:字符串 分割成 字符串数组

  • LeetCode 131. 分割回文串

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

  • LeetCode 131 [Palindrome Partiti

    原题 给定一个字符串s,将s分割成一些子串,使每个子串都是回文串。返回s所有可能的回文串分割方案。 样例给出 s ...

  • 108. 分割回文串 II

    描述 给定字符串 s, 需要将它分割成一些子串, 使得每个子串都是回文串. 最少需要分割几次? 样例 思路: 考虑...

  • 递归与回溯:131.分割回文串

    /** 题目 给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。 返回 s 所有可能的分割方案。 ...

网友评论

      本文标题:palindrome-partitioning分割成回文串 go

      本文链接:https://www.haomeiwen.com/subject/nehxoftx.html