问题:
对于一组数字,在不改变原有数字顺序的情况下,删除 m 个数字,使得剩下的 n – m 个数字组成的数最大。
思路:
- 维护一个栈:
- 使用一个栈来存储当前选择的数字。
- 当遇到一个新的数字时,比较它与栈顶元素。如果新数字更大,并且可以删除栈顶元素(即 m > 0),则弹出栈顶元素。
- 处理剩余数字:
- 如果在遍历完所有数字后,还有剩余的删除次数 m,继续从栈中弹出元素直到 m 减少到 0。
- 构建结果:
- 最终栈中的元素即为保留的最大数。
AI编码实现:(这个实现运行结果不对)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
package main import ( "fmt" "strconv" ) func removeKdigits(num string, k int) string { var stack []byte for i := 0; i < len(num); i++ { digit := num[i] // 如果栈顶元素小于当前元素,并且可以删除栈顶元素 for k > 0 && len(stack) > 0 && stack[len(stack)-1] < digit { stack = stack[:len(stack)-1] // 弹出栈顶元素 k-- } stack = append(stack, digit) } // 如果还有剩余的删除次数,继续从栈中弹出元素 for k > 0 { stack = stack[:len(stack)-1] k-- } // 构建结果字符串,并去掉前导零 result := bytes.TrimLeft(stack, "0") if len(result) == 0 { return "0" } return string(result) } func main() { num := "27886483" m := 3 result := removeKdigits(num, m) fmt.Printf("删除 %d 个数字后,最大的数是: %s\n", m, result) } |
- 初始化栈:
- 使用一个切片 stack 来模拟栈的行为。
- 遍历输入字符串:
- 对于每个字符(数字),检查是否可以删除栈顶元素以使结果更大。
- 如果可以删除栈顶元素,则弹出栈顶元素,并减少剩余的删除次数 k。
- 将当前字符压入栈中。
- 处理剩余的删除次数:
- 在遍历完所有字符后,如果还有剩余的删除次数 k,继续从栈中弹出元素直到 k 减少到 0。
- 构建结果字符串:
- 使用 bytes.TrimLeft 去掉结果字符串中的前导零。
- 如果结果为空,则返回 “0”。
对于输入 num = “27886483” 和 m = 3,程序的输出将是:
1 |
删除 3 个数字后,最大的数是: 8883 |
这个结果确保了在不改变原有数字顺序的情况下,删除 3 个数字得到的最大可能的数。
补充:
stack[len(stack)-1] < digit 的这个逻辑 AI生成的时候是错的,写的是 stack[len(stack)-1] > digit; 手动修改后算法可用
由上面逻辑来看,真心不是小学生能够完成的。