给定一个数n如23121;给定一组数字a如[2 4 9],求由a中元素组成的小于n的最大数
a: 1-9的不同数字
n:int32
分析
从n的高位到低位遍历 假设当前位是bit, 找寻arr满足条件的数分类讨论:
- 找到arr[i] == bit, 当前位置更新为bit,继续遍历低位
- 找到最大的arr[i] < bit, 那么当前位置更新位arr[i], 后面所有位置全部更新为 max(arr)
- min(arr) > bit, 当前位找不到比n更小,舍弃所有高位,低位全部选最大
经过上述的遍历筛选之后,能得到两个答案:
- 满足条件的最大。直接返回即可。
- 找到ans==n。继续分析ans==n,从低位遍历ans的每一位,从arr中找更小的一个值替换a. 找到值,替换,返回替换后的ansb. 所有值遍历完,找不到更小,所有位置都是min(ans) 那么返回0,表示找不到更小值
实现
Golang
func solve(n int, arr []int) int { // 将n从高位到低位用数组存储,方便按位置检索 // 123 => []int{1,2,3} nArr := []int{} for n > 0 { // 加到数组前面 nArr = append([]int{n % 10}, nArr...) n /= 10 } // 将arr进行排序,方便找寻min,max 寻值可以用2分,更快,不过因为arr长度最大只有9[1-9], 所以也可以直接遍历 sort.Ints(arr) // 按梳理条件分类讨论 ans := 0 // 从高位开始,定位n的位置 pos := 0 for pos < len(nArr) { bit := nArr[pos] pos++ // 找到第一个>bit的索引idx, 那么arr[idx-1] <= bit idx := 0 for idx < len(arr) && arr[idx] <= bit { idx++ } if idx == 0 { // 当前找不到比bit更小的值,往前看有没有位置可以选更小元素 // 1. 找到,那么该位置选择更小,后续位置全部最大 // 2. 没有找到,前置全部是最小值,则舍弃最高位,后续位置全部选最大 // pos当前在下一位,回到上一位,-2 pos -= 2 for pos >= 0 { cur := ans % 10 ans /= 10 if arr[0] == cur { pos-- continue } // 存在更小值,找到更小值,替换 idx := 0 for arr[idx] < cur { idx++ } ans = ans*10 + arr[idx-1] pos++ break } // 如果没有找到,则去除最高位,此时ans=0 if pos <= 0 { pos = 1 } // 低位全部选择最大 for pos < len(nArr) { ans = ans*10 + arr[len(arr)-1] pos++ } return ans } // arr[idx-1] 是小于等于bit的最大值 if arr[idx-1] < bit { ans = ans*10 + arr[idx-1] // 低位全部选择最大 for pos < len(nArr) { ans = ans*10 + arr[len(arr)-1] pos++ } return ans } // arr[idx-1] == bit ans = ans*10 + bit // 继续遍历低位 } // 循环内没找到答案,此时ret=n 逆序遍历,找到更小的位置,替换 pos = len(nArr) - 1 for pos >= 0 { bit := nArr[pos] pos-- idx := 0 // 找到arr[idx]=bit, idx-1为要的元素 for idx < len(arr) && arr[idx] < bit { idx++ } // 找到了 if idx > 0 { ans = ans*10 + bit for pos >= 0 { bit := nArr[pos] ans = ans*10 + bit pos-- } // 因为是逆序遍历得到的答案,所以将ret逆序 return reverse(ans) } // 没找到,继续遍历 ans = ans*10 + bit } // 没找到 return 0 } func reverse(v int) int { ans := 0 for v > 0 { ans = ans*10 + v%10 v /= 10 } return ans }
验证:
示例1: 23121 [4,2,9] 22999 示例2: 19238479 [1,4,2,3,7] 17777777 示例3: 192482 1,5,3,2 155555 示例4: 333112342 4,5,6,7 77777777 示例5: 4441242 4,5,6 666666 示例6: 23121 2,3,4 22444