Java 缺少多个数字的未排序数组

Java 缺少多个数字的未排序数组,java,Java,给定一个大小为N的数组,其中有多个等于-1的缺失数字,我需要找到缺失的数字并打印更新的数组,数组中[1-N]中的所有数字都不允许对数组进行排序 我试着先在纸上解决它,但没能 例如: 数组[2,4,6,5,-1,8,-1] 结果: [2,4,6,5,3,8,7]或[2,4,6,5,3,8,7]它们中的任何一个都是好的,并且其时间复杂度应该更高 即使是一个提示也有助于实现对缺失数字的查找,当c为常数时,O(c*N)仍然是线性时间。这意味着“线性时间”要求仍然允许您在阵列上进行多次传递,只要传递的数量

给定一个大小为N的数组,其中有多个等于-1的缺失数字,我需要找到缺失的数字并打印更新的数组,数组中[1-N]中的所有数字都不允许对数组进行排序

我试着先在纸上解决它,但没能

例如: 数组[2,4,6,5,-1,8,-1]

结果: [2,4,6,5,3,8,7]或[2,4,6,5,3,8,7]它们中的任何一个都是好的,并且其时间复杂度应该更高

即使是一个提示也有助于实现对缺失数字的查找,当
c
为常数时,O(c*N)仍然是线性时间。这意味着“线性时间”要求仍然允许您在阵列上进行多次传递,只要传递的数量不变。(只要通过次数不是
N
的函数)

因此:

过程1:使用所有值(缺失值和存在值)填充贴图

传递2:从映射中删除数组中可以找到的每个值

第3步:将数组中的每个
-1
替换为映射中的一个数字,从映射中删除该数字。

O(c*N)
c
为常数时仍然是线性时间。这意味着“线性时间”要求仍然允许您在阵列上进行多次传递,只要传递的数量不变。(只要通过次数不是
N
的函数)

因此:

过程1:使用所有值(缺失值和存在值)填充贴图

传递2:从映射中删除数组中可以找到的每个值


第3步:用映射中的数字替换数组中的每个
-1
,从映射中删除该数字。

用数字1-n填充位集:

BitSet bits = new BitSet(n + 1);
bits.set(1, n + 1, true);
迭代数组,取消位集中非-1的位:

for (int b : arr) {
  if (b != -1) bits.clear(b);
}
迭代数组并用位集中的一个设置位替换-1s:

for (int a = 0, prev = 0; a < arr.length; ++a) {
  if (arr[a] == -1) {
    arr[a] = prev = bits.nextSetBit(prev + 1);
  }
}
for(int a=0,prev=0;a
用数字1-n填充位集:

BitSet bits = new BitSet(n + 1);
bits.set(1, n + 1, true);
迭代数组,取消位集中非-1的位:

for (int b : arr) {
  if (b != -1) bits.clear(b);
}
迭代数组并用位集中的一个设置位替换-1s:

for (int a = 0, prev = 0; a < arr.length; ++a) {
  if (arr[a] == -1) {
    arr[a] = prev = bits.nextSetBit(prev + 1);
  }
}
for(int a=0,prev=0;a
好吧,这是我的尝试。它必须比我原来想象的做更多的簿记工作

        int[] vals = { 2, -1,6,-1,-1};
        // min value is the start of the sequence
        int min = Integer.MAX_VALUE;
        int bitmap = 0;
        // records the -1 indices.
        List<Integer> missing = new ArrayList<>();

        // loops at most n times.
        for (int i = 0; i < vals.length; i++) {
            int v = vals[i];
            if (v >= 0) {
                // set value in bitmap 
                bitmap |= (1 << v);
                // and find minimum entry
                if (v < min) {
                    min = v;
                }
            } else {
                // save index of missing numbers.
                missing.add(i);
            }
        }

        // get rid of low order zero bits.
        bitmap>>=min;

        int i = 0;
        // Loops at most, n times
        while(!missing.isEmpty()) {
            // check bitmap for a missing number in sequence
            if ((bitmap & 1) == 0) {
                // and fill it in
                vals[missing.get(0)] = i + min;
                missing.remove(0);
            }
            bitmap>>=1;
            i++;
        }
        System.out.println(Arrays.toString(vals));

int[]vals={2,-1,6,-1,-1};
//最小值是序列的开始
int min=整数最大值;
int位图=0;
//记录-1指数。
缺少列表=新建ArrayList();
//循环次数最多为n次。
对于(int i=0;i=0){
//在位图中设置值
位图|=(1>=最小值;
int i=0;
//循环次数最多为n次
而(!missing.isEmpty()){
//按顺序检查位图是否缺少数字
如果((位图&1)==0){
//填写
VAL[缺少。获取(0)]=i+min;
缺失。删除(0);
}
位图>>=1;
i++;
}
System.out.println(Arrays.toString(vals));

好吧,这是我的尝试。它必须比我原来想象的做更多的簿记工作

        int[] vals = { 2, -1,6,-1,-1};
        // min value is the start of the sequence
        int min = Integer.MAX_VALUE;
        int bitmap = 0;
        // records the -1 indices.
        List<Integer> missing = new ArrayList<>();

        // loops at most n times.
        for (int i = 0; i < vals.length; i++) {
            int v = vals[i];
            if (v >= 0) {
                // set value in bitmap 
                bitmap |= (1 << v);
                // and find minimum entry
                if (v < min) {
                    min = v;
                }
            } else {
                // save index of missing numbers.
                missing.add(i);
            }
        }

        // get rid of low order zero bits.
        bitmap>>=min;

        int i = 0;
        // Loops at most, n times
        while(!missing.isEmpty()) {
            // check bitmap for a missing number in sequence
            if ((bitmap & 1) == 0) {
                // and fill it in
                vals[missing.get(0)] = i + min;
                missing.remove(0);
            }
            bitmap>>=1;
            i++;
        }
        System.out.println(Arrays.toString(vals));

int[]vals={2,-1,6,-1,-1};
//最小值是序列的开始
int min=整数最大值;
int位图=0;
//记录-1指数。
缺少列表=新建ArrayList();
//循环次数最多为n次。
对于(int i=0;i=0){
//在位图中设置值
位图|=(1>=最小值;
int i=0;
//循环次数最多为n次
而(!missing.isEmpty()){
//按顺序检查位图是否缺少数字
如果((位图&1)==0){
//填写
VAL[缺少。获取(0)]=i+min;
缺失。删除(0);
}
位图>>=1;
i++;
}
System.out.println(Arrays.toString(vals));

您发布的两个数组似乎是相等的。“它们中的任何一个都很好”为什么不包含1?@AndyTurner,因为只缺少两个数组,这意味着缺少1、3和7,因为最大值为8,它们需要构成一个范围。@WJS“数组中从[1-n]开始的所有数字是多少?”那么是什么意思?@AndyTurner我想这是在显示一个合法范围的值。所以[1-n]的任何子范围都是有效的。你发布的两个数组似乎是相等的。“它们中的任何一个都是好的”为什么不包含1?@AndyTurner,因为只缺少两个,这意味着缺少1、3和7,因为最大值为8,它们需要构成一个范围。@WJS“从[1-n]开始的数组中的所有数字”是什么意思?@AndyTurner我认为这显示了一个合法范围的值。那么[1-n]的任何子范围将是有效的。在实践中,对于除超大数据集以外的任何数据集,这可能比我的映射解决方案更有效。但在理论上,这可能没有线性运行时间,因为
nextSetBit()
函数可能会对下一位执行线性搜索。(我不确定这一点,但我无法想象他们还能如何实现它。)因此,
nextSetBit()
的时间复杂度是
N
的函数,随后是
N
where
nextSetBit()上循环的时间复杂度
被使用为
N
平方。@MikeNakis不,它仍然是线性的。您不必每次都从位集的开头开始搜索。气泡排序中的内部循环也不是每次都从数组的开头开始,但它仍然被视为
O(N^2)
算法。这是