使用递归回溯的方式,来生成数,
1、对arr的数字进行排序
2、将n拆成数组
3、将n中的数字从高位到低位开始跟arr中的数字,从大到小比较,
4、如果相等继续进行下一位的比较
5、如果没有找到,回溯,进行减小上一位
6、如果小于,后续的用最大值补充
具体实现如下
package main
import (
"fmt"
"sort"
"strconv"
)
// dfs 函数:返回第 index 位后可组成的最大的数字,包括第 index 位
func dfs(arr, nums []int, preEq bool, index int) int {
// 如果考虑完了最后一位,那么能组成的最大值为0
if index == len(nums) {
return 0
}
if preEq {
for i := len(arr) - 1; i >= 0; i-- {
if index == len(nums)-1 {
//最后一位需要特殊处理,如果包含相等的情况可以省略掉这个if
if arr[i] < nums[index] {
return arr[i]
}
} else {
if arr[i] <= nums[index] {
temp := dfs(arr, nums, arr[i] == nums[index], index+1)
if temp == -1 {
//后边的部分没有找到合适的,返回了-1,所以需要当前位置再往前寻找
continue
}
return arr[i]*pow(10, len(nums)-index-1) + temp
}
}
}
if index == 0 {
return dfs(arr, nums, false, index+1)
}
//没有找到的情况下,返回-1,作为回溯条件
return -1
} else {
//如果有不相等的情况,直接用最大值来计算
return arr[len(arr)-1]*pow(10, len(nums)-index-1) + dfs(arr, nums, false, index+1)
}
}
// compareNum 函数:比较整数大小
func compareNum(arr []int, num int) bool {
return arrToNum(arr) <= num
}
// arrToNum 函数:将整数数组转换为整数
func arrToNum(arr []int) int {
numStr := ""
for _, digit := range arr {
numStr += strconv.Itoa(digit)
}
num, _ := strconv.Atoi(numStr)
return num
}
// pow 函数:计算底数的幂
func pow(base, exponent int) int {
result := 1
for i := 0; i < exponent; i++ {
result *= base
}
return result
}
// find 函数:主函数
func find(N int, arr []int) int {
arrSorted := make([]int, len(arr))
copy(arrSorted, arr)
sort.Ints(arrSorted)
var nums []int
for _, digit := range strconv.Itoa(N) {
num, _ := strconv.Atoi(string(digit))
nums = append(nums, num)
}
return dfs(arrSorted, nums, true, 0)
}
func main() {
arrInputList := [][]int{
{2, 3, 4, 5},
{2, 3, 4, 5},
{2, 3, 4, 5},
{2, 3, 4, 5},
{2, 3, 4},
{9, 2},
}
NList := []int{1234, 2234, 2231, 2134, 33121, 9991}
ansList := []int{555, 2233, 2225, 555, 32444, 9929} //验证部分
for i := range NList {
ans := find(NList[i], arrInputList[i])
fmt.Println(NList[i], arrInputList[i], ans, ansList[i])
}
}
执行结果:
1234 [2 3 4 5] 555 555
2234 [2 3 4 5] 2233 2233
2231 [2 3 4 5] 2225 2225
2134 [2 3 4 5] 555 555
33121 [2 3 4] 32444 32444
9991 [9 2] 9929 9929