当前位置: 首页 > 知识库问答 >
问题:

用高效的算法从数组中获取丢失的数字??[重复]

沈枫涟
2023-03-14

我正在做以下编程练习:Number Zoo Patrol。声明是:

背景:

你在一个数字动物园工作,似乎有一个数字不见了!

动物园的工作人员不知道少了什么数字,也太无能了,无法弄清楚,所以他们雇佣你来为他们做这件事。

万一动物园又丢了一个数字,他们希望你的程序能正常工作,不管总共有多少个数字。任务:

编写一个函数,将唯一数字的混洗数组从1到n,其中缺少一个元素(可以是包括n在内的任何数字)。返回这个缺失的数字。示例:

findNumber([1,3,4])应为2 findNumber([1,2,3])应为4 findNumber([4,2,3])应为1

我有困难,因为这是第一次测试时间复杂度的练习。有一个测试可以检查你的算法对于大型数组的执行时间是否少于一秒。以下是我写的测试:

import static org.junit.Assert.assertEquals;

import java.util.concurrent.TimeUnit;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.Timeout;

public class NumberZooPatrolSampleTest {

    @Rule
    public Timeout globalTimeout = new Timeout(1, TimeUnit.SECONDS);

    @Test
    public void testDescriptionExamples() {
        assertEquals(2, findMissingNumber(1, 3));
        assertEquals(1, findMissingNumber(2, 3, 4));
        assertEquals(12, findMissingNumber(13, 11, 10, 3, 2, 1, 4, 5, 6, 9, 7, 8));
    }

    @Test
    public void testPerformanceIsLinear() {
        // Solutions with linear runtime should finish in about 200 to 300 ms.
        // 1. Generate an array with 999,999 numbers with increasing and
        //    decreasing values interleaved so sorting algorithms which
        //    are able detect pre-sorted arrays would still need
        //    at least loglinear time.
        // 2. Find the missing number 100 times.
        int[] numbers = generateNumbers(1_000_000, 66_667);
        for (int i = 0; i < 249_999; i++) {
            int temp = numbers[i * 2];
            numbers[i * 2] = numbers[999_997 - i * 2];
            numbers[999_997 - i * 2] = temp;
        }
        for (int i = 0; i < 100; i++)
            findMissingNumber(numbers.clone());
    }

    private static int findMissingNumber(int ... numbers) {
        return NumberZooPatrol.findMissingNumber(numbers);
    }

    private static int[] generateNumbers(int bound, int missingNumber) {
        if (missingNumber < 1 || missingNumber > bound)
            throw new IllegalArgumentException("Missing number is not in allowed range");
        int[] numbers = new int[bound - 1];
        int pos = 0;
        for (int i = 1; i <= bound; i++)
            if (i != missingNumber)
                numbers[pos++] = i;
        return numbers;
    }

}

我的第一个方法是逐个比较数组中的数字与该位置应该有的数字:

import java.util.*;
import java.util.stream.*;
public class NumberZooPatrol {
  public static int findMissingNumber(int[] numbers) {
    int[] clone = numbers.clone();
    Arrays.sort(clone);
    int i = 0;
    for(; i < clone.length; i++){
      if(clone[i] != i+1){
        break;
      }
    }
    return i+1;
  }
}

然而,它没有通过时间复杂度测试。

此外,我使用了另一种方法,其中我们得到了范围之和与当前数组总和之间的差值:

import java.util.*;
import java.util.stream.*;
public class NumberZooPatrol {
  public static int findMissingNumber(int[] numbers) {
    if(numbers.length == 0) return 1;
    int[] clone = numbers.clone();
    Arrays.sort(clone);
    int range = IntStream.rangeClosed(1,clone[clone.length-1]).sum();
    int sum = IntStream.of(clone).sum();
    return range - sum == 0 ? clone.length + 1 : range - sum;
  }
}

当我们执行时间复杂度测试时,它也会超时。

此外,我还阅读了:

  • 如何在Java中生成序列整数的列表或数组
  • 如何用java流对整数列表求和
  • 制作数组的副本

如何用有效的算法从数组中得到缺失的数字?‽?

共有1个答案

通煜祺
2023-03-14

您可以使用两种方法在O(n)时间复杂度下完成它:

>

  • 您可以使用n(n 1)/2公式找到数字的总和,并减去实际总和以获得丢失的数字。

    您还可以 XOR 1 到 n 范围内的所有数字以及输入中的数字。结果将是缺少的数字。这是有效的,因为,具有自身的数字的XOR为零,而0 XOR任何数字都是数字本身。

    例如:如果输入是[1,3,4],缺少的数字是2。

    (1 XOR 2 XOR 3 XOR 4) XOR (1 XOR 3 XOR 4) = 
    (1 XOR 1) XOR (3 XOR 3) XOR (4 XOR 4) XOR 2 =
    0 XOR 0 XOR 0 XOR 2 = 
    0 XOR 2 =
    2
    

  •  类似资料:
    • 我不知道搜索或谷歌它,所以我在这里问它。我有一个具有固定大小的整数数组,并且完全符合此逻辑。 现在我得到了一个数字,例如26。我将找到其总和将构成此数字的数字,在本例中为[2,8,16] 对于20个数字,它将是[4,16] 对于40它是[8,32] 对于63,它是所有这些数字[1,2,4,8,16,32] 正确的算法是什么? 我严格地知道,总有这样一种延续,即数字是前一个值的两倍。以及只有给定数组

    • 我有以下数组 我想从这个数组中得到唯一的值。所以我希望我的结果是这样的 我使用了数组唯一函数,但无法得到结果 如果我有两个索引,这是有效的,但是对于多个索引呢?

    • 给定一个具有n个键的数组或对象,我需要找到长度的所有组合 给定的是可变的。 目前我正在使用这个: 输出为: 因此,如果我想从< code>n=4中得到二项式系数< code>x=3,我选择所有长度等于3的字符串。{abc,abd,acd,bcd}。 所以我分两步做。 有没有一种复杂度更小、效率更高的算法? 链接: 解决方案性能 (JSPerf)

    • 我一直在尝试获取

    • 我收藏了这样的文件: 我想找到所有的有效载荷。_id,其状态为真/假。预期结果是 到目前为止,我有这样的东西。 不确定如何为数组中的元素添加条件。

    • 如何计算数组中数字的平均值? 看看我是如何获取数据的; 我想知道每个阵列的平均值,所以: 我在React工作。我从React Redux中的选择器获取数据。我用它来计算每个用户的平均评论。 代码: