程式碼隨想錄day24 || 93 復原IP地址,78 子集, 90 子集2

周公瑾55發表於2024-08-09

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...)...)

}

相關文章