有一个数组,其中除了一个单元格之外的所有单元格都是0,我们想要找到该单个非零单元格的索引。问题是,每次检查此数组中的单元格时,该非零元素都将执行以下操作之一:
例如,如果该元素当前位于第10位,并且我检查arr[5]
中的内容,那么在我选中arr[5]
后该元素可能位于第9,10或11位。
我们只需要找到元素当前所处的位置,而不是它开始的位置(这是不可能的)。
困难的部分是,如果我们写一个for循环,真的无法知道元素当前是在你面前还是在你身后。
如果它有帮助,可以提供更多上下文:
答案 0 :(得分:0)
不要忘记关于循环的一切。 将此数组复制到另一个数组,然后检查哪些单元格现在为非零。例如,如果你的主数组是mainArray [],你可以使用:
int temp[sizeOfMainArray]
int counter = 0;
while(counter < sizeOfArray)
{
temp[counter] == mainArray[counter];
}
//then check what is non-zero in copied array
counter = 0;
while(counter < sizeOfArray)
{
if(temp[counter] != 0)
{
std::cout<<"I Found It!!!";
}
}//end of while
答案 1 :(得分:0)
或许可以采用一种方法:
i - 有四个索引变量f,f1,l,l1。 f指向0,f1指向1,l指向n-1(数组的末尾),l1指向n-2(倒数第二个元素)
ii - 检查f1和l1处的元素 - 它们中的任何一个都不为零吗?如果是这样的话。如果没有,检查f和l处的元素(以查看元素是否已跳回1)。
iii - 如果f和l仍然为零,则递增索引并重复步骤ii。当f1&gt;停止L1
答案 2 :(得分:0)
Iff 对数组索引进行等式检查会使非零元素跳转。
为什么不考虑一种我们不需要使用数组索引进行相等性检查的方法?
int check = 0;
for(int i = 0 ; i < arr.length ; i++) {
check |= arr[i];
if(check != 0)
break;
}
Orrr。也许你可以继续阅读arr[mid]
。非零元素将在那里结束。有一天。推理:帕特里克·特伦廷似乎把它放在了他的答案中(有点,不是那么,但你会得到一个想法)。
如果您有关于阵列的一些信息,也许我们可以提出一种更为狡猾的方法。
答案 3 :(得分:0)
忽略1在数组的第一个单元格中的简单情况如果迭代遍历数组依次测试每个元素,则必须最终到达1在单元格i + 2中的位置i。因此,当你阅读单元格i + 1时,将会发生三件事之一。
重新读取i + 1单元格会在案例3中找到1,但只是给它另一个机会在案例1和2中移动,因此基于重读的策略不会起作用。
因此,我的选择是采用蛮力方法,如果我继续扫描阵列,那么我将在某个时刻点击案例1并找到难以捉摸的1。
答案 4 :(得分:0)
假设:
数组不是真正的数组。鉴于这个问题,这很明显。我们得到了一些类似于数组的类。
数组主要是隐藏的。唯一的公共操作是[]和size()。
数组被混淆了。我们无法通过检索它的地址来获取任何信息,然后分析该位置的内存。即使我们遍历系统的整个内存,由于一些先进的加密手段,我们也无法做到。
数组的每个字段都可能成为承载该字段的第一个字段。
我们知道触发后如何改变位置的可能性。
概率控制算法:
它可能能够通过控制概率流来优化这一点,但这需要基于游荡事件,可能需要一些研究。
尝试解决此问题的算法不会在一段时间后终止。对于复杂性,我们将分析平均情况。
实施例: 跳跃概率为1/3,如果试图跳出界限则没有任何反应
初始化:
第一次迭代:尝试[0] - &gt;失败
第二次迭代:尝试[2],因为1/7是最大值,这是第一个具有1/7 - >的字段。成功(示例现在应该很清楚,当然这可能不会在另一个例子上如此快速地工作,没有兴趣在很多迭代中这样做,因为手动计算的概率很麻烦,需要实现它。如果那个跳到左边,我们就不会这么快检查它,即使它在那里停留了一段时间)