给定一个数组,找出数组缺少的最小的正整数
来源:互联网 发布:大数据如何影响制造业 编辑:程序博客网 时间:2024/05/22 16:07
题目使这样的:请设计一个高效算法,查找数组中未出现的最小正整数。
给定一个整数数组A,请返回数组中未出现的最小正整数。
测试样例:
[-1,2,3,4]
返回1
一看到这个题目我想到的是用另外的一个数组B,长度为A的长度+1,来存储遍历数组A的数的值。 if(A[i] == i+1) B[i+1] = A[i]。然后遍历数组B,出现空缺的地方即是最小未出现的正整数。但是假如要求额外空间复杂度为O(1),那就没办法了。有的人会想到排序,但是排序最好需要O(nlog2n)的时间复杂度。如果要求时间复杂度为O(n),并且空间复杂度为O(1),那么要怎么做呢?这方法是我在牛客网上看到的。听完之后,感觉特别不可思议,实在是太厉害了。在我的理解里,这是一种正向和逆向结合的思想。从前往后和从后往前不停地进行,理想情况和实际情况实时地更新,最后的临界点必然是两者相等。
在这个算法里,有两个额外变量。一个是match,初始值为0。用来标记从正整数1开始已经连续出现的正整数个数。比如说[3, 5, 2, 1, 6] 出现的连续正整数序列为{1 2 3 },所以match= 3;还有一个变量是maxMatch,初始值是整个数组的长度,因为数组在没遍历之前,无法得知其中的元素,所以看作是最理想的情况:里面的数刚好是1到n。
说了两个变量之后,便是算法的部分了。
首先从第0位置开始,如果A[0]=match+1;那么说明出现了下一个连续的正整数,所以match++;
如果A[0] != mach+1,那么有几种情况。
第一种情况是,A[0]<=match,那么这个值是我们不需要的,因为match之前的正整数已经出现了。所以这时候剩下的数最多能使match的值达到maxMatch-1,因为这个无效的元素,需要占用一个位置。同理如果A[0]>maxMatch,这个值也是不需要的,maxMatch-1;还有就是如果这个数在match和maxMatch的范围之内,我们需要判断这个数应该在的位置上,是否已经有了这个数。比如说A[0]=3,那么我们只需要比较A[2]位置上是否是3,如果是那么这个数也不是我们需要的,这是maxMatch-1;以上几种情况都是遍历的位置上的数是不需要的,那么我们应该把后面的数调到这个位置上,进行重新搜索。
还有一种情况就是 match+1<A[0]<=maxMatch,并且A[0]应该在的位置上的数不是A[0],那么这个数就是我们可能需要的,所以把它放在它应该在的位置。比如说[3, 5, 2, 1, 6],3应该在的位置是2,A[2]上的数字是2,不等于3.所以3应该放在2的位置。这时我们应该交换两个数的位置A[0] <=> A[2];
这样一直搜索下去,最终便是达到临界点,然后结束搜索。最终的结果便是match+1;
public static int firstMissingPosition(int[] nums) { if(null == nums){ throw new NullPointerException("输入的数组为空..."); }else if(0 == nums.length){return 1;} int match = 0; int maxMatch = nums.length; while(match<maxMatch){ if(nums[match]==match+1){ match++; }else if(nums[match]<=match || nums[match]>maxMatch || nums[nums[match]-1] == nums[match]){ maxMatch--; nums[match] = nums[maxMatch]; }else {int temp = nums[match];nums[match] = nums[temp-1];nums[temp-1] = temp;} } return match+1; }
代码量很少,但是思路真的是很精妙。不得不为之赞叹!
- 给定一个数组,找出数组缺少的最小的正整数
- 【算法】(遇到的问题)给定一个数组,找出不在数组中的最小的那个数字
- 给定一个数组,找出不在数组中的最小的那个数字
- 给定一个数组,找出不在数组中的最小的那个数字
- 给定一个数组,找出不在数组中的最小的那个数字
- 给定一个无序整型数组,找出数组中未出现的最小整数
- 给定一个数组,找出数组的峰值。返回其下标
- 找出给定数组或文件中最小的k个数
- 给定一个正整数数组求组合起来的最大值
- Java给定一个数组,数组元素是一些正整数,求这些正整数收尾详解得出的最大数或最小数
- 从一个无序数组中找出缺少的值。
- 给定一个未排序数组, 找出其中最长的等差数列
- 首个正数,给定一个无序整形数组,找出第一个不在数组里的正整数。要求时间复杂度0(n),空间复杂度o(1)
- 如何在一堆正整数中(数组arr)找出与给定正整数(num)最接近的那个数(result)
- 给定一个无序数组,找到其中最小的K个数
- 给定一个数组,找出这个和最大的连续子数组的和
- 找出一个数组中最小的K个元素
- 整型数组处理算法(九)给定任意一个正整数,求比这个数大且最小的“不重复数”[2014百度笔试题]
- login.jsp
- 【追求进步】数组中的逆序对
- 循环(2)
- SQL SERVER恢复数据错误解决:The backup set holds a backup of a database other than the existing
- json文件的相关细节
- 给定一个数组,找出数组缺少的最小的正整数
- ES-MongoDB学习6_用 mongodb + elasticsearch 实现中文检索
- Mysql备份和还原
- android 如何给图片添加水印
- DataNode本地数据存储和管理--ncp_block_verification.log.curr和dncp_block_verification.log.prev
- Java总结 第三篇 常用工具类
- 剑指offer 19 顺时针打印矩阵
- ORACLE 等待事件
- NSPredicate