I am given an array arr
of integers that is sorted in ascending or descending order. If arr
contains at least two distinct elements, I need to find the longest arr.last(n)
that has exactly two distinct elements (i.e., with the largest n
). Otherwise, it should return arr
. Some examples are:
arr = [6, 4, 3, 2, 2]
, then [3, 2, 2]
is to be returnedarr = [6, 4, 3, 3, 2]
, then [3, 3, 2]
is to be returnedarr = [1]
, then arr
is to be returned.I would be grateful for suggestions on how to compute the desired result.
答案 0 :(得分:4)
这里使用take_while
的方法效率很低:
def last_non_dupe(array, count = 2)
result = [ ]
array.reverse.take_while do |n|
result << n
result.uniq.length <= count
end.reverse
end
可以使用自动Set
对其进行改进:
require 'set'
def last_non_dupe(array, count = 2)
result = Set.new
array.reverse.take_while do |n|
result << n
result.length <= count
end.reverse
end
无论哪种情况,您都要做:
last_non_dupe([6, 4, 3, 2, 2])
# => [3, 2, 2]
对于更长或更短的列表,可以根据需要更改count
参数。
答案 1 :(得分:3)
def last_two_different(arr, count)
arr.reverse_each.
lazy.
chunk(&:itself).
first(count).
flat_map(&:last).
reverse
end
last_two_different [6, 4, 3, 2, 2], 2 #=> [3, 2, 2]
last_two_different [3, 4, 3, 3, 2], 2 #=> [3, 3, 2]
last_two_different [3, 4, 3, 3, 2], 3 #=> [4, 3, 3, 2]
last_two_different [3, 4, 3, 3, 2], 4 #=> [3, 4, 3, 3, 2]
last_two_different [1, 2], 2 #=> [1, 2]
last_two_different [1, 1], 2 #=> [1, 1]
last_two_different [1], 2 #=> [1]
last_two_different [], 2 #=> []
步骤如下。
arr = [6, 4, 3, 2, 2]
count = 2
enum0 = arr.reverse_each
#=> #<Enumerator: [6, 4, 3, 2, 2]:reverse_each>
我们可以将此枚举器转换为数组以查看其将生成的值。
enum0.to_a
#=> [2, 2, 3, 4, 6]
首先,假设我们写了以下内容。
enum1 = enum0.chunk(&:itself)
#=> #<Enumerator: #<Enumerator::Generator:0x00005c29be132b00>:each>
enum1.to_a
#=> [[2, [2, 2]], [3, [3]], [4, [4]], [6, [6]]]
我们想要由count #=> 2
生成的前enum1
个元素,我们可以从中提取所需的结果。这告诉我们我们需要一个惰性枚举器。
enum2 = enum0.lazy
#=> #<Enumerator::Lazy: #<Enumerator: [6, 4, 3, 2, 2]:reverse_each>>
enum3 = enum2.chunk(&:itself)
#=> #<Enumerator::Lazy: #<Enumerator:
# #<Enumerator::Generator:0x00005c29bdf48cb8>:each>>
enum3.to_a
#=> [[2, [2, 2]], [3, [3]], [4, [4]], [6, [6]]]
a = enum3.first(count)
#=> [[2, [2, 2]], [3, [3]]]
b = a.flat_map(&:last)
#=> [2, 2, 3]
b.reverse
#=> [3, 2, 2]
答案 2 :(得分:3)
不确定效率,但这是另一种实现方法:
arr = [6, 4, 3, 2, 2]
uniq = arr.uniq.last(2) # => [3, 2]
arr.select{|e| uniq.include?(e)} # => [3, 2, 2]