第一周
来源:互联网 发布:c语言字符串大小写转换 编辑:程序博客网 时间:2024/05/16 08:59
First Missing Positive 第一周 2017/9/10
题目的源地址–https://leetcode.com/problems/first-missing-positive/description/
题目描述:
Given an unsorted integer array, find the first missing positive integer.
For example,
Given [1,2,0] return 3,
and [3,4,-1,1] return 2.
Your algorithm should run in O(n) time and uses constant space.
就是根据给出的无排序的整数数组,找出其中最小的缺失的正整数。其中要求算法的时间复杂度为O(n),而且要使用恒定的空间。
再说自己的理解之前,先把代码放上
class Solution {public: int firstMissingPositive(vector<int>& nums) { int result = 1, CurrentVal, NextVal; int size = nums.size(); set<int> Set; for (int i = 0; i < size; i++) { Set.insert(nums[i]); } set<int>::iterator its; set<int>::iterator it_temp; for (its = Set.begin(); its != Set.end(); its++) { CurrentVal = *its; if (CurrentVal > 0) { if (CurrentVal == result) { if (++its != Set.end()) { NextVal = *its; if (CurrentVal + 1 != NextVal) { result = CurrentVal + 1; break; } else { its--; if (its == Set.end()--) { result = *its + 1; break; } result++; } } else { result = CurrentVal + 1; break; } } else { break; } } } return result; }};
解决上面的问题,我自己的思路是先将无序数组变成有序,然后就可以很快地找出最小的缺失的正整数。首先题目要求时间复杂度为O(n),这可以将平时大多数用的排序算法排除了。那么将如何对数组排序呢?我想过一个不用排序的方法,就是定义一个数组值全为0的array,然后遍历vector,将array[vector[i]]的值设为1,表示已经出现,最后只需遍历这个数组array,就可以找到最小的缺失的正整数。但因为并不知道无序数组值的范围,所以就无法声明数组,而且题目要求恒定空间,所以不能使用动态数组。即便可以,如何无序数组的值范围很大,声明的数组就会很大,遍历起来会浪费很多时间,同时也会浪费部分空间,所以我最后选择使用set。set默认是从小到大排序的,而且不重复,所以将vector的值插入到set后就可以用于比较。
在排序完后就可以遍历set,找出答案。在遍历的过程中需要比较将前一个数和后一个数比较,看看两者之间是否只相差1,如果不是,就返回后一个数的值,这是从大方向来看,但需要注意几种特殊情况:
1)数组只有一个数,如果这个数为1,就返回2,但如果这个数大于1,就返回1。
2)数组中的值是按照大小排序的,两两之间并没有间隔,那么就返回最后一个数+1。
3)如果数组的值全为非正整数,那么就返回1。
上面图片是最后的结果,从图片可以看出,虽然算法是通过了,但算法的运行时间是6ms,而我这个算法的排名是比较靠后的,我觉得这是因为使用了set的缘故,而且这个算法的圈复杂度是挺大的,所以这个题目是有更好的算法来解决,只是自己没想到,如果想到的话,自己会再重新刷一遍的。