经典的问题陈述是:给定一个未排序的整数数组A
,找到A
中不存在的最小正整数。
[3, 2, 1, 6, 5] -> 4
[2, 3, 4, 5] -> 1
[1, 2, 3, 4] -> 5
在一个经典的问题陈述中,你只得到一个数组,你可以在这里、这里和这里找到很多关于这个问题的解决方案和资源。
在我的问题中,你得到了两个数组,A
和B
,长度均为N
。构造一个长度为 N
的数组 C
,其“最小缺失整数”是可能的最大值。C[i]
必须是 A[i]
或 B[i]
。
A = [1, 2, 4, 3], B = [1, 3, 2, 3] =-> C = [1, 2, 4, 3] answer = 5
A = [4, 2, 1, 6, 5], B = [3, 2, 1, 7, 7] =-> C = [3, 2, 1, 6, 5] answer = 4
A = [2, 3], B = [4, 5] =-> C = [2, 5] answer = 1
我们如何以< code>O(N)的最坏情况时间和空间复杂度解决这个问题?
假设:
1<= N <= 100,000
1<= A[i], B[i] <= 100,000,000
请检查这个代码片段,我已经写在Java8
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Run {
private int solution(int[] A) {
List<Integer> positiveIntegerList = Arrays.stream(A).distinct().filter(e -> e > 0).boxed().sorted(Comparator.naturalOrder()).collect(Collectors.toList());
final int i = 1;
if (!positiveIntegerList.isEmpty()) {
final int missingMax = positiveIntegerList.get(positiveIntegerList.size() - i) + i;
List<Integer> range = IntStream.rangeClosed(i, positiveIntegerList.get(positiveIntegerList.size() - i))
.boxed().collect(Collectors.toList());
AtomicInteger index = new AtomicInteger();
return range.stream().filter(e -> !e.equals(positiveIntegerList.get(index.getAndIncrement()))).findFirst().
orElse(missingMax);
} else {
return i;
}
}
public static void main(String[] args) {
Run run = new Run();
int[] intArray = new int[]{1, 3, 6, 4, 1, 2};
System.out.println(run.solution(intArray));
}
}
如果遍历数组并构建一个图,其中在a或B中遇到的每个唯一整数都成为一个顶点,并且每对整数a[i]和B[i]在两个顶点之间创建一条边,则该图最多有2×N个顶点,因此该图所占用的空间与N成线性关系。
然后,对于图中的每一条边,我们将决定其方向,即它连接的两个整数中的哪一个将用于数组C。最后,我们将再次迭代数组,对于每一对整数,我们查看图中相应的边,以了解要使用的整数。
我相信决定图中方向所需的操作都可以在线性时间内完成到N(如果我错了,请纠正我),所以整个算法应该具有O(N)的时间和空间复杂度。
决定图形中边方向的规则如下:
在遍历数组并查找图形中相应的边时,标记当两个顶点多重连接时已使用的整数,以便第二次使用另一个整数。之后,你可以选择其中之一。
例:
A = [1,6,2,9,7,2,5,3,4,10]
B = [5,8,3,2,9,7,1,2,8,3]
图表:
1===5 6---8---4 9---2===3---10
| |
--7--
我们找到周期 [1
有向图:
1<=>5 6<--8-->4 9-->2<=>3-->10
^ |
|-7<-
结果:
C = [1,6,2,2,9,7,5,3,4,10]
缺少的第一个整数是8,因为我们不得不牺牲它来保存[6,8,4]子图中的4和6。
此算法适用于对数字范围[0..n2]
内的数字进行的O(n)
算术运算,以及处理输入的时间。
[1… n]
内的数字替换为n 2
。这不会改变结果。1,2,3,…, n-1, n, n 2
的图,对于所有0
现在,问题等效于找到一种方法来引导边缘,使得度数为0的最小顶点是可能的最大值。
>
在图表中找到连接的组件。
对于具有 v
个顶点和 e
个边的每个连接元件,e
>
如果e==v-1
,它是一棵树。所有引导边的方法都将导致一个顶点的度数为0,并且可以证明,对于树中的所有顶点,都存在一种引导边的方法,使得它是唯一的度数为0的顶点。
方法:
将树的根定在那个顶点,然后使每条边都从父节点指向子节点。
当然,最好(贪婪地)选择度数为0的顶点作为数量最多的顶点。
如果 e
证明(和构造边缘方向的方法)留给读者。
所以...我有:int array[]={-8,2,0,5,-3,6,0,9}; 我想找到一个最小的正数(在上面的列表中是2)
我试图找到给定排序数组的最大K数。 ex:输入- 到目前为止,我编写的代码返回最大的K元素,但它需要返回最大的K数字。任何帮助都将不胜感激。
我正在尝试解决一个leetcode类型问题,这是一个实践问题,它伴随着即将到来的代码测试,我需要为工作做一个,我遇到了麻烦。任何人都可以帮助我了解出了什么问题? 我基本上是在寻找暴力选项,因为我不知道algos/DS。 编写一个函数: 功能溶液(A); 给定一个包含 N 个整数的数组 A,返回 A 中未出现的最小正整数(大于 0)。 例如,给定A = [1,3,6,4,1,2],函数应该返回5。
求一个未排序数组的中值,我们可以对n个元素做O(nlogn)时间的min-heap,然后我们可以逐个抽取n/2个元素得到中值。但是这种方法需要O(nlogn)时间。 我们能在O(n)时间内通过某种方法做同样的事情吗?如果可以,那么请告诉或建议一些方法。
请帮忙!!
问题内容: 我们需要在分配中递归地找到一个数组中的第二个最小整数。但是,为了更好地理解该主题,我想先通过本网站进行迭代,然后自己进行递归。 不幸的是,迭代地进行相当混乱。我知道该解决方案很简单,但我无法解决。 到目前为止,以下是我的代码: 这适用于一些数字,但不是全部。数字会变化,因为内部if条件的效率不如外部if条件的效率。 禁止阵列重排。 问题答案: 试试这个。当最小的数字是第一个时,第二个条