置换的最优化

时间:2017-10-13 08:54:13

标签: ruby

我正在练习,我得到this question

  

你必须创建一个带正整数的函数,并返回由相同数字组成的下一个更大的数字,如果没有更大的数字可以用这些数字组成,则返回-1

如何更快地进行此搜索?

def next_bigger(n)
  u = n.to_s.split("").permutation(n.to_s.length).to_a.map { |x| x.join("").to_i }.uniq.sort  # create sorted array of all permutations
  u.push(-1) # Add -1 to end of array
  return u[u.index(n)+1] # print next bigger or -1
end
# u is sorted array
# n is input

我将测试传递给数字"1234567980"它太大而且超时(最长为12000毫秒)。

2 个答案:

答案 0 :(得分:1)

@marmeladze感谢您的帮助您的回答让我选择重新开始作为https://repl.it/Mapt/2

这是最好的方式来做到这一点... !!不是我的! !
def next_bigger n max = maxed n (n+1..max).each { |i| return i if max == maxed(i) } -1 end def maxed n n.to_s.split('').sort.reverse.join.to_i end

答案 1 :(得分:0)

不要将置换转换为数组。它将严重打击内存。

Array#permutation(如果没有给出阻止)返回枚举器。您可以安全地使用.next方法行走。

2.4.0-rc1 :033 > b = a.chars.permutation
 => #<Enumerator: ["b", "a", "r"]:permutation> 
2.4.0-rc1 :034 > b.next
 => ["b", "a", "r"] 
2.4.0-rc1 :035 > b.next
 => ["b", "r", "a"] 
2.4.0-rc1 :036 > b.next
 => ["a", "b", "r"] 
2.4.0-rc1 :037 > b.next
 => ["a", "r", "b"] 
2.4.0-rc1 :038 > b.next
 => ["r", "b", "a"] 
2.4.0-rc1 :039 > b.next
 => ["r", "a", "b"] 
2.4.0-rc1 :040 > b.next

不确定我是否正确阅读了问题,但您可以按照以下方法进行操作。

def next_bigger(a)
  digits = a.to_s.chars.sort.permutation

  # ruby 2.4 provides .digits method for integers
  # but seems online interpreter version is 2.3.1
  # your can also  try this. 
  # digits =  number.to_s.split(//).map{|chr| chr.to_i}

  b = digits.next
  begin
    while a >= arr_to_int(b) do 
        b = digits.next
      end
  rescue
    return -1
  end
  return arr_to_int(b)
end

def arr_to_int arr
  arr.join.to_i
end


puts next_bigger(9)==-1
puts next_bigger(111)==-1
puts next_bigger(531)==-1
puts next_bigger(12)==21
puts next_bigger(513)==531
puts next_bigger(2017)==2071
puts next_bigger(12) == 21
puts next_bigger(414) == 441
puts next_bigger(144) ==  414
puts next_bigger(1234567890) #1234567908