java—在未排序数组中查找唯一数字的问题

30byixjq  于 2021-07-07  发布在  Java
关注(0)|答案(1)|浏览(396)

一种方法,它接收一个未排序的数组,该数组由相邻的相等数对和一个没有对的数对组成。例如-

  1. int [] a = {6,6,18,18,-4,-4,12,9,9};
  2. int [] c = {8,-7,-7,3,3,0,0,10,10,5,5,4,4};

代码必须返回索引和数字本身。
现在的问题是关于时间复杂性,我知道o(logn)可以解决这个问题,但我的代码有一半是有效的:

  1. public static int findSingle (int [] a) {
  2. int high = a.length-1;
  3. int low = 0;
  4. int mid = 0;
  5. int found = 0;
  6. mid = ((high-low)/2);
  7. while (mid >= 1) {
  8. if (a[mid] != a[mid-1])
  9. low = mid +1;
  10. mid =((high - low)/2);
  11. if (mid == 1)
  12. found = a[mid];
  13. if (a[mid] == a[mid-1])
  14. high = mid-1;
  15. mid = ((high - low)/2);
  16. }
  17. return found;
  18. }

现在给出这个数组:

  1. int [] d = {8,8,-7,3,3,0,0,10,10,5,5,4,4};

它说数字在第8个元素中,这显然不是真的,在某些数组中它也会出错。有什么问题吗?
编辑:我注意到我应该将“mid”指定为high+low/2,但这两种方法都不能解决问题。

c6ubokkw

c6ubokkw1#

你在正确的轨道上,但是你的代码有一些问题。

  1. while (mid >= 1)

为什么mid小于或等于1是退出条件?您希望退出条件是在找到值时,该值可以位于数组中的任何位置,而不仅仅是在开始时。我要把退出条件改为 high 以及 low ,就像在普通的二进制搜索中一样。

  1. mid = ((high-low)/2);

首先,这个公式找不到中间的数字 high 以及 low . 这应该是 ((high+low)/2) . 此外,这些列表的性质使得保持数据的奇偶性非常重要 mid 始终如一。我要确保 mid 通过添加 mid += mid%2; 什么时候 mid 已设置。

  1. low = mid +1;
  2. ...
  3. high = mid-1;

再次强调的是 high 以及 low 是非常重要的。两者应始终保持平衡。我们知道这一点 mid 是平的,所以 high 以及 low 不应被抵消 mid 以+/-1。

  1. if (mid == 1)
  2. found = a[mid];

这是代码中最大的问题。首先,您是要查找单个数字的索引还是单个数字的值?你说你在找索引,但你的代码却在找 a[mid] 这是一个值。我下面的代码找到了索引,但这很容易修改。第二,你只有在 mid 是1。这意味着您的代码将始终返回0或0 a[1] .
还有几张便条。没有理由设置 mid 每个循环两次,并检查两次 a[mid] != a[mid-1] 以及 a[mid] == a[mid-1] . 相反,每个循环设置一次mid,检查其中一个条件,然后使用 if/else . 而且,没有理由使用 found . 相反,只要使用 high 或者 low 当循环退出时,现在它正正确退出。
最终代码:

  1. public static int findSingle (int [] a) {
  2. int high = a.length-1;
  3. int low = 0;
  4. int mid = 0;
  5. while (high != low) {
  6. mid = ((high + low) / 2);
  7. mid += mid%2;
  8. if (a[mid] != a[mid-1])
  9. low = mid;
  10. else
  11. high = mid - 2;
  12. }
  13. return high;
  14. }

我还没有完全测试过这个,但是从我看到的几个测试用例来看,它似乎是有效的。
编辑:
原来有个虫子(谢谢亚历克斯·鲁登科)。固定版本:

  1. public static int findSingle (int [] a) {
  2. int high = a.length-1;
  3. int low = 0;
  4. int mid = 0;
  5. while (high != low) {
  6. mid = ((high + low) / 2);
  7. mid -= mid%2;
  8. if (a[mid] == a[mid+1])
  9. low = mid + 2;
  10. else
  11. high = mid;
  12. }
  13. return high;
  14. }
展开查看全部

相关问题