最大回文数

找出最大的一个回文整数,比如105881这个整数,最大的回文数是81518。因为组成105881这个数中的1、0、5、8、8、1可以组成81518这个回文整数,81518这个数是可以组成的最大的回文数。

def palindrome(number)
  #先将整数转化成一个数组
  array = number.to_s.chars
  #如果组成n的数字中,每一个只包含一个,那么直接返回最大的那个数字
  return array.map(&:to_i).sort.last if array.all? {|ele| array.count(ele) == 1}
  #找出包含有2个以上的数字,用hash来存一下
  h = {}
  array.each {|ele| h.store ele,array.count(ele)}
  #如果某个数字重复了奇数次,那么则去减掉一个,使得最后的tmp数组是由x个数字组成,并且每个数字的重复次数都是偶数次,然后按大小升序排序。keep_if先删除掉重复次数为1的数字,each是将重复了奇数次的数字的次数减1变成偶数次。后面的join.split.sort_by则是将hash变成数组
  tmp = h.keep_if {|k,v| v > 1}.each {|k,v| h[k] = v.odd? ? v-1 : v}.map {|k,v| k * v}.join.split("").sort_by(&:to_i)
  s = ""
  #判断array的长度是否与tmp相同,如果相同,即可以认为array包含的数字都是重复了偶数次的数字,是肯定能组成回文数的
  #如果不相同,则说明tmp组成的回文数,在最中间加上一个数字,也能组成回文数,只需要把没用到的最大的一个数字取出来就行了
  if array.size > tmp.size
    a = array.uniq.sort_by(&:to_i)
    until a.empty?
      n = a.pop
      #判断最大的数字是否在tmp中就已经用完了,如果没用完,直接用这个数就行。
      if array.count(n) > tmp.count(n)
        s << n
        break
      end
    end
  end
  #按从小到大的顺序,往两边增加,直接到tmp数组中的数字用完
  until tmp.empty?
    s = tmp.shift + s
    s = s + tmp.shift
  end
  s
end

你可能感兴趣的