每个Codefighters:
注意:写一个O(n)时间复杂度和O(1)附加的解决方案 空间复杂性,因为这是你要求你做的事情 真实的采访。
给定一个数组a,它只包含1到1之间的数字 a.length,找到第二个的第一个重复数字 发生具有最小指数。换句话说,如果还有更多 超过1个重复的数字,返回第二个数字 出现的索引小于另一个出现的索引 号码呢。如果没有这样的元素,则返回-1。
实施例
对于a = [2,3,3,1,5,2],输出应为firstDuplicate(a)= 3。
有两个重复:数字2和3.第二次出现3 索引比第二次出现的索引小2,所以 答案是3。
对于a = [2,4,3,5,1],输出应为firstDuplicate(a)= -1。
所以这就是我想出来的。它工作但最终测试失败,因为它运行超过4000毫秒。我不知道我还能做些什么。有什么提高速度的想法吗?
function firstDuplicate(a) {
var test = [],
lowest = undefined;
for (var i=0; i<a.length; i++) {
if (test.indexOf(a[i]) > -1) {
lowest = lowest || i;
if (i < lowest) {
lowest = i;
}
}
else {
test.push(a[i]);
}
}
return lowest ? a[lowest] : -1;
}
这是我的第二次尝试,但在最后一次测试中仍未通过......
function firstDuplicate(a) {
var low = undefined,
last = -1;
for (var i=0; i<a.length; i++) {
last = a.lastIndexOf(a[i])
if (last > i && (low === undefined || last < low)) {
low = last;
}
}
return low !== undefined ? a[low] : -1;
}
答案 0 :(得分:8)
要求提供了如何解决这个问题的线索。数组中包含的数字集必须与以下标准匹配:
只有1到a.length范围内的数字
换句话说,只有小于或等于数组长度的正数。如果数组包含十个数字,则它们都不会大于10.
凭借这种洞察力,我们有办法跟踪我们已经看过的数字。我们可以将数字本身视为数组的索引,修改该索引处的元素(在这种情况下使其为负数),如果我们遇到相同的数字并且该索引处的元素小于零,那么我们就知道了已经看过了。
console.clear()
const test1 = [2, 3, 3, 1, 5, 2]
const test2 = [2, 4, 3, 5, 1]
function firstDuplicate(a) {
for (let i of a) {
let posi = Math.abs(i) - 1
if (a[posi] < 0) return posi + 1
a[posi] = a[posi] * -1
}
return -1
}
console.log(firstDuplicate(test1))
console.log(firstDuplicate(test2))
console.log(firstDuplicate([2,2]))
console.log(firstDuplicate([2,3,3]))
console.log(firstDuplicate([3,3,3]))
&#13;
原始不正确答案
跟踪已经看过的数字并返回之前看过的第一个数字。
console.clear()
const test1 = [2, 3, 3, 1, 5, 2]
const test2 = [2, 4, 3, 5, 1]
function firstDuplicate(a){
const seen = {}
for (let v of a){
if (seen[v]) return v
seen[v] = v
}
return -1
}
console.log(firstDuplicate(test1))
console.log(firstDuplicate(test2))
&#13;
正如评论中所指出的,这个答案需要额外的O(n)空间,而不是O(1)额外的空间。
答案 1 :(得分:3)
我们将利用数组@Override public void onCreate(Bundle savedInstanceState) {
...
ImageView imageView = (ImageView) findViewById(R.id.my_image_view);
GlideApp.with(this).load("http://i.imgur.com/qFeBmOF.png").into(imageView);
}
仅包含1到a
范围内的数字这一事实,以便记住通过反转看到的值数组中该位置的任何符号。
a.length
&#13;
答案 2 :(得分:1)
通过测试的Python 3版本。
def firstDuplicate(a):
oldies={}
notfound=True
for i in range(len(a)):
try:
if oldies[a[i]]==a[i]:
notfound=False
return a[i]
except:
oldies[a[i]]=a[i]
if notfound:
return -1
答案 3 :(得分:0)
您在两个示例中都在迭代n
次。
如果数组长度为200,000,000并且在索引3处找到第一个副本,该怎么办?循环仍然不必要地运行200,000,000次。
所以我们的想法是在找到第一个副本后突破循环。
您可以使用break或return
。