概念
刷题
- 组合总和
剪枝操作: 对 candidates 进行排序,如果 candidates[i] > target, i后面的元素无需继续遍历
- 组合总和II
- 分割回文串
优化:
使用动态规划
上面的代码还存在一定的优化空间, 在于如何更高效的计算一个子字符串是否是回文字串。上述代码isPalindrome函数运用双指针的方法来判定对于一个字符串s, 给定起始下标和终止下标, 截取出的子字符串是否是回文字串。但是其中有一定的重复计算存在:
例如给定字符串"abcde", 在已知"bcd"不是回文字串时, 不再需要去双指针操作"abcde"而可以直接判定它一定不是回文字串。
具体来说, 给定一个字符串s, 长度为n, 它成为回文字串的充分必要条件是s[0] == s[n-1]且s[1:n-1]是回文字串。
大家如果熟悉动态规划这种算法的话, 我们可以高效地事先一次性计算出, 针对一个字符串s, 它的任何子串是否是回文字串, 然后在我们的回溯函数中直接查询即可, 省去了双指针移动判定这一步骤.
具体参考代码如下:
var isPalindRome [][]bool
func partition(s string) (result [][]string) {
computePalindRome(s)
path := make([]string, 0)
var backTracking func(int)
backTracking = func(startIndex int) {
if startIndex >= len(s) {
tmpPath := make([]string, len(path))
copy(tmpPath, path)
result = append(result, tmpPath)
}
for i := startIndex; i < len(s); i++ {
if isPalindRome[startIndex][i] {
path = append(path, s[startIndex:i+1])
backTracking(i + 1)
path = path[:len(path)-1]
}
}
}
backTracking(0)
return
}
func computePalindRome(s string) {
isPalindRome = make([][]bool, len(s))
for i := 0; i < len(isPalindRome); i++ {
isPalindRome[i] = make([]bool, len(s))
}
for i := len(s) - 1; i >= 0; i-- {
for j := i; j < len(s); j++ {
if i == j {
isPalindRome[i][j] = true
}
if j-i == 1 {
isPalindRome[i][j] = s[i] == s[j]
}
if j-i > 1 {
isPalindRome[i][j] = s[i] == s[j] && isPalindRome[i+1][j-1]
}
}
}
}
总结
在Go语言中,排序可以通过多种方式实现,包括使用标准库中的sort包提供的函数,或者自定义比较函数来实现更复杂的排序逻辑。下面是一些常用的排序方法:
- 使用sort包进行排序 Go语言的sort包提供了对切片(slice)进行排序的函数。你可以使用sort.Ints, sort.Float64s, sort.Strings等函数对基本类型的切片进行排序,或者使用sort.Slice和sort.SliceStable来自定义排序逻辑。 示例1: 对整数切片排序
package main
import (
"fmt"
"sort"
)
func main() {
numbers := []int{5, 3, 8, 4, 2}
sort.Ints(numbers)
fmt.Println(numbers) // 输出: [2 3 4 5 8]
}
示例2: 对字符串切片排序
package main
import (
"fmt"
"sort"
)
func main() {
words := []string{"pear", "apple", "lime", "banana"}
sort.Strings(words)
fmt.Println(words) // 输出: [apple banana lime pear]
}
- 使用sort.Slice自定义排序逻辑 如果你需要对切片进行更复杂的排序(例如,根据结构体或多个字段排序),可以使用sort.Slice。这个函数允许你提供一个比较函数来自定义排序逻辑。 示例3: 对结构体切片按字段排序
package main
import (
"fmt"
"sort"
)
type Person struct {
Name string
Age int
}
func main() {
people := []Person{
{"Bob", 31},
{"John", 42},
{"Michael", 17},
{"Jenny", 26},
}
// 按年龄排序
sort.Slice(people, func(i, j int) bool { return people[i].Age < people[j].Age })
fmt.Println("Sorted by age:", people) // 按年龄排序输出结果可能因运行环境而异,但大致如此。
}