这是一个面试问题:
找到可以由给定数字的相同数字组成的下一个最大数字..
输入:4765,输出:5467
如果使用array
,这并不难。
- 我们将数字转换为数字数组。
x
我们扫描数组,记录下一个邻居更大的最新(最低位置)数字(比如 as )- 如果下一个邻居更小(这意味着它正在下降),那么我们记录大于 x 的最小数字(比如 as
y
) - 最后,我们交换 x 和 y
但是,在 OCaml 中,如果我们使用list
,那么我不知道该怎么做。似乎该算法使递归变得困难。
有什么建议么?
编辑:
请注意我希望有一种实用的方式(使用list)
编辑
按照@comingstorm 的建议,我是这样实现的:
exception NotFound;;
let rev_list_of_int n =
let rec process n =
let x = n / 10 and y = n mod 10
in
if x = 0 && y = 0 then []
else
y::(process x)
in
process n;;
let find_next_by_list n =
let l = rev_list_of_int n
in
let rec find_x before_x x after_x =
match after_x with
| [] | _::[] -> (before_x, -1, after_x)
| hd1::hd2::tl ->
if hd1 > hd2 then (hd1::before_x, hd2, tl)
else find_x (hd1::before_x) x (hd2::tl)
in
let (bx, x, ax) = find_x [] (-1) l (* ax is rev *)
in
if x = -1 then raise NotFound
else
let rec find_y x path = function
| [] -> raise NotFound
| hd::tl ->
if hd > x then (path, hd, tl)
else find_y x (hd::path) tl
in
let (left, y, right) = find_y x [] (List.rev bx) (* left is rev, right is not *)
in
(* rev ax, then y, then right, then x, then rev left*)
(List.rev_append (y::ax) right) @ (x::List.rev left)