我很新,在练习中遇到了问题。 我解决了这个问题,可以用,但是检查更多数字-最大长度aprox时太慢了。 = 1.000.000。 怎么写才能更快地解决?
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="target.php">
<table name="criteria_search" align="left" border="1" style="margin-right:70px">
<tr><td class="dataLabel"><strong>Add Rule : </strong>
<select name="rule" id="rule" class="action">
<optgroup label="Simple Rules">
<option value="instructions" selected="selected"> </option>
<option value="email">Email</option>
<option value="assigned">Assigned Racecourse</option>
</optgroup>
</select>
</td><td class="dataLabel" id="email" style="display:none">
<b>email:</b>
<br/><label><input type="radio" name="email_c" value="true_ex"> yes</label>
<br/><label><input type="radio" name="email_c" value="false"> no</label>
<br/><label><input type="radio" name="email_c" value="soon"> not yet</label>
</td>
<td class="dataLabel" id="assigned" style="display:none">
Racecourse<br/>
<b>Assigned To: </b>
<select name="selected_assigned_location">
<option value=""></option>
<option value="a">racecourse A</option>
<option value="b">racecourse B</option>
<option value="c">racecourse C</option>
</select>
</td>
</tr>
</table>
</form><br style="clear:both" />
<div id="show"></div>
测试:
def find_dups_miss(arr)
((arr.sort.first..arr.sort.last).to_a - arr.sort) + [arr.select{|item| arr.count(item) > 1}.uniq.sort]
end
它需要找到丢失的数字和重复项。
错误消息: 为什么我的代码超时? 我们的服务器配置为仅允许一定时间来执行您的代码。在极少数情况下,服务器可能会承担过多的工作,并且根本无法有效地运行您的代码。尽管大多数情况下,此问题是由效率低下的算法引起的。如果您多次看到此错误,则应尝试进一步优化代码。
答案 0 :(得分:3)
我们得到了一个整数数组arr
,其属性是它包含min_val
和max_val
之间的每个整数,但其中一个为min_val, max_val = arr.minmax
。我们希望确定丢失的整数以及arr
中的重复值。
require 'set'
def missing_and_dups(arr)
smallest, largest = arr.minmax
dups = Set.new
all = arr.each_with_object(Set.new) { |n,all| dups << n if all.add?(n).nil? }
[(smallest+largest)*(largest-smallest+1)/2 - all.sum, dups.to_a]
end
missing_and_dups [10,9,8,9,6,1,2,4,3,2,5,5,3]
#=> [7, [9, 2, 5, 3]]
请注意,如果要添加的元素已经在集合中,则Set#add?返回nil
。而不是使用
n
((smallest..largest).to_a - arr).first
我利用了以下事实
all.sum + n = (smallest+largest)*(smallest+largest-1)/2
答案 1 :(得分:1)
这大约是我现在能解决这个问题的速度
def find_dups_miss(arr)
groups = arr.group_by(&:itself)
arr.minmax.reduce(:upto).to_a - groups.keys << groups.select {|_,v| v.size > 1}.keys.sort
end
基于发布的Array
首先,我们将Array
元素单独分组
{10=>[10], 9=>[9, 9], 8=>[8], 6=>[6], 1=>[1], 2=>[2, 2], 4=>[4], 3=>[3, 3], 5=>[5, 5]}
然后,我们根据Enumerator
的最小和最大值(arr.minmax.reduce(:upto)
)创建一个Array
,将其隐式覆盖到Array
(to_a
)并从上一个分组中减去所有keys
:
arr.minmax.reduce(:upto).to_a - groups.keys
#=> [7]
然后,我们收集原始Array
中多次出现的所有数字:(我对它们进行了排序是因为对期望的结果进行了排序)
groups.select {|_,v| v.size > 1}.keys.sort
#=> [2, 3, 5, 9]
并使用Array#<<
将此Array
推回到上一步中创建的
#=> [7,[2, 3, 5, 9]]
如果仅遗漏了一个数字,则以下内容会更快一些,因为它不会在第一个遗漏的数字上产生额外的Array
和短路:
def find_dups_miss(arr)
groups = arr.group_by(&:itself)
[groups.select {|_,v| v.size > 1}.keys.sort].unshift(arr.minmax.reduce(:upto).find {|n| groups[n].nil?} )
end
另外,对于非常大的Array
:
groups.collect {|k,v| k if v.size > 1 }.compact.sort
似乎比
更有效率groups.select {|_,v| v.size > 1}.keys.sort
答案 2 :(得分:0)
我同意最好将其放在代码审查中,但是要回答您的问题,可以使用更好的数据结构来解决此问题,请考虑将其用作哈希:
def find_dups_missing(arr)
min, max = arr.min, arr.max
hash = {}
min.upto(max) { |i| hash[i] = :sentinel }
arr.each { |el| hash[el] == :sentinel ? hash[el] = 1 : hash[el] += 1 }
hash.select { |_, v| v == :sentinel }.keys << hash.select { |_, v| v != :sentinel && v > 1 }.keys
end
我们循环遍历,构建一个哈希,其中每个键是一个从min
到max
的数字,并且该值指向一个只是占位符的对象(我称之为sentinel
) 。
接下来,我们遍历数组,询问哈希值是否仍在其占位符位置,如果是,则将值设置为1
,但如果不是,则仅递增。这样,我们就可以跟踪何时第一次看到某个值以及随后的几次(即重复)。
然后,在全部说完之后,我们得到一个如下所示的哈希:
{1=>1, 2=>2, 3=>2, 4=>1, 5=>2, 6=>1, 7=>:sentinel, 8=>1, 9=>2, 10=>1}
我们知道值> 1
在哪里,我们有重复项,我们还知道值仍在sentinel
哪里,我们从未在数组中看到它,这是我们的差距。
总的来说,此方法在O(n)
个空间中平均O(n)
个时间运行。