93 復原ip地址
func restoreIpAddresses(s string) []string {
// 字串分割問題,考慮回溯演算法
var path, res []string
if len(s) < 4 {
return res
}
backtracking(s, &path, &res)
return res
}
func backtracking(s string, path *[]string, res *[]string) {
if len(s) == 0 && len(*path) == 4{
//var copypath = make([]string, len(*path))
//copy(copypath, *path)
r := strings.Join(*path, ".") // join操作將*path底層陣列轉換為字串變數,所以不需要重新賦值
*res = append(*res, r)
return
}
// 剪枝
if len(*path) > 4 {
return
}
for i := 0; i < len(s); i++{
if vaildIp(s[0 : i+1]) {
*path = append(*path, s[0 : i+1])
backtracking(s[i+1 : ], path, res)
*path = (*path)[0 : len(*path) - 1]
}
}
return
}
func vaildIp (s string) bool {
// 處理0開頭的兩位或者三位ip
if len(s) > 1 && s[0] == '0' {
return false
}
ip, _ := strconv.Atoi(s)
if ip > 255 {
return false
}
return true
}
78 無重複元素子集
func subsets(nums []int) [][]int {
// 子集問題,同樣考慮回溯演算法,但是這次要樹的所有節點包括首位的空節點都要收集
var path = []int{}
var res = [][]int{}
res = append(res, path) // 收集首位空節點
backtracking(nums, &path, &res)
return res
}
func backtracking(nums []int, path *[]int, res *[][]int) {
if len(nums) == 0 {
return
}
for i:=0; i<len(nums); i++{
*path = append(*path, nums[i])
// 對於path每次變動,res都要收錄
var copypath = make([]int, len(*path))
copy(copypath, *path)
*res = append(*res, copypath)
backtracking(nums[i+1 : ], path, res)
*path = (*path)[0 : len(*path) - 1]
}
return
}
90 有重複元素子集
func subsetsWithDup(nums []int) [][]int {
// 子集問題,同樣考慮回溯演算法,但是這次要樹的所有節點包括首位的空節點都要收集,重複問題只需要先排序然後相鄰元素判斷相等跳過即可
var path = []int{}
var res = [][]int{}
res = append(res, path) // 收集首位空節點
nums = quicksort(nums)
backtracking(nums, &path, &res)
return res
}
func backtracking(nums []int, path *[]int, res *[][]int) {
if len(nums) == 0 {
return
}
for i:=0; i<len(nums); i++{
// 去重
if i > 0 && nums[i] == nums[i-1] {
continue
}
*path = append(*path, nums[i])
// 對於path每次變動,res都要收錄
var copypath = make([]int, len(*path))
copy(copypath, *path)
*res = append(*res, copypath)
backtracking(nums[i+1 : ], path, res)
*path = (*path)[0 : len(*path) - 1]
}
return
}
func quicksort(nums []int) []int{
if len(nums) == 0 {
return nil
}
// 每次根據nums長度隨機選取一個值作為基準變數,避免都選取首位,出現【9,8,7,6,5,4,3,2,1】這種極端情況
r := rand.New(rand.NewSource(time.Now().Unix())) // 建立rand例項
povid := nums[r.Intn(len(nums))]
var left, right, equal []int
for _, num := range nums {
if num > povid {
right = append(right, num)
}else if num < povid {
left = append(left, num)
}else {
equal = append(equal, num)
}
}
// 遞迴排序左右子陣列並拼接結果
left = quicksort(left)
right = quicksort(right)
return append(left, append(equal, right...)...)
}