Home > Net >  longest subsequence: missing last element
longest subsequence: missing last element

Time:05-07

Hi guys I'm working on the longest subsequence algorithm, the idea is to find the subsequence of numbers from an array. I'm using Ruby, so far I'm missing the last number of the subsequence, this is my code:

def sequence_length1(array)
  array.sort! 
  secuencia_mayor = []
  array.each_with_index do |numero, indice|
    numero   1 == array[indice 1] ? secuencia_mayor << numero  : ''
  end
  return secuencia_mayor
end

p sequence_length1([100, 4, 200, 1, 3, 2]) #length=4
p sequence_length1([29, 27, 28, 55, 100, 84]) #length=3

The code has a bug: the last element will never be part of the secuencia_mayor array due to the conditional, my question is: what should I change in the code to overcome this issue?

Thanks a lot

CodePudding user response:

To use the approach you have taken you need to save the longest known sequence found so far (or its starting index and length) as you loop through the elements of the array. Here is one way to do that.

def sequence_length1(array)
  array.sort!
  secuencia_mayor = []
  candidate = []
  array.each do |numero|
    if candidate.empty? || candidate.last   1 == numero
      candidate << numero
    else
      secuencia_mayor = candidate.dup if candidate.size > secuencia_mayor
      candidate = []
    end
  end
  secuencia_mayor = candidate.dup if candidate.size > secuencia_mayor
  secuencia_mayor
end
sequence_length1 [100, 4, 200, 1, 3, 2]
  #=> [1, 2, 3, 4]
sequence_length1([29, 27, 28, 55, 100, 84]) #length=3
  #=> [27, 28, 29]

Another way, which is more Ruby-like, is to use Enumerable#slice_when and Enumerable#max_by.

def seq(arr)
  arr.sort.slice_when { |a,b| b != a   1 }.max_by(&:size)
end
seq [100, 4, 200, 1, 3, 2]
  #=> [1, 2, 3, 4]
seq [29, 27, 28, 55, 100, 84]
  #=> [27, 28, 29]

The steps are as follows.

arr = [100, 4, 200, 1, 3, 2]
c = arr.sort
  #=> [1, 2, 3, 4, 100, 200]
enum = c.slice_when { |a,b| b != a   1 }
  #=> #<Enumerator: #<Enumerator::Generator:0x00007fa9fd913238>:each>
d = enum.max_by(&:size)
  #=> [1, 2, 3, 4]
d.size
  #=> 4

We can see the elements that enum will generate and pass to max_by by converting the enumerator to an array:

enum.to_a
  #=> [[1, 2, 3, 4], [100], [200]]

enum.max_by(&:size) is shorthand for enum.max_by { |e| e.size }.


  • Related