题目要求
给定一个未排序的整数数组,找出其中没有出现的最小的正整数。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/first-missing-positive
示例 1:
输入: [1,2,0]
输出: 3
示例 2:
输入: [3,4,-1,1]
输出: 2
示例 3:
输入: [7,8,9,11,12]
输出: 1
说明:
你的算法的时间复杂度应为O(n),并且只能使用常数级别的空间。
基础补习
桶排序
c++实现案例
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void bksort(float A[], int l, int h) {
int size = h - l + 1;
vector<vector<float> > b(size);//有size个数据,就分配size个桶
for (int i = l; i <= h; i++) {
int bi = size * A[i];//元素A[i]的桶编号
b[bi].push_back(A[i]);//将元素A[i]压入桶中
}
for (int i = 0; i < size; i++)
sort(b[i].begin(), b[i].end());//桶内排序
int idx = l;//指向数组A的下标
for (int i = 0; i < size; i++) {//遍历桶
for (int j = 0; j < b[i].size(); j++) {//遍历桶内元素
A[idx++] = b[i][j];
}
}
}
int main() {
float A[] = { 0.78,0.17,0.39,0.26,0.72,0.94,0.21,0.12,0.23,0.68 };
bksort(A, 2, 9);
for (int i = 0; i < 10; i++)
cout << A[i] << " ";
参考代码(有误)
【排序(C++实现)】:桶排序
题解
数组解法
https://github.com/soulmachine/leetcode
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Solution{
public:
int firstMissingPositive(int A[],int n) {
bucket_sort(A,n);
for (int i = 0; i < n; ++i)
if (A[i] != (i + 1))
return i + 1;
return n + 1;
}
private:
static void bucket_sort(int A[],int n) {
for (int i = 0; i < n; i++) {
while (A[i] != i + 1) {
// 当前位置元素 == 当前元素值所对应位置上的值
if (A[i] <= 0 || A[i] > n || A[i] == A[A[i] - 1])
break;
swap(A[i],A[A[i] - 1]);
}
}
}
};
主要思路
这里的主要思路是先利用桶排序把元素交换到对应序号的位置上,即占位(2换到A[1],4换到A[5],等等)。
数组中对应位置没有相应元素处为其他元素,所以经过排序后对数组从0开始查找对应位置上是否存在对应元素即可。
Vector改写版
习惯了vector。。。
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
// 先进行桶排序
bk_sort(nums);
// 找出最小的桶(此时并没有将各桶进行最后的合并)
if(nums.size()==0) return 1;
for(int i=0;i<nums.size();i++){
if(nums[i]!=(i+1))
return i+1;
}
return nums.size()+1;
}
private:
static void bk_sort(vector<int>& nums){
for(int i=0;i<nums.size();i++){
while(nums[i]!=i+1){
if(nums[i]<=0||nums[i]>nums.size()||nums[i]<nums[nums[i]-1])
break;
swap(nums[i],nums[nums[i]-1]);
}
}
}
};
然后。。。竟然超出时间限制了!尴尬,再看别的题解吧。。。
https://leetcode-cn.com/problems/first-missing-positive/solution/cchao-guo-100kan-wei-wei-da-lao-ti-jie-hou-xie-de-/
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
vector<int>::size_type n=nums.size();
if(n==0) return 1;
for(size_t i=0;i<n;i++) {
while(nums[i]>0&&nums[i]<=n&&nums[i]!=nums[nums[i]-1]&&i+1!=nums[i])
swap(nums[i],nums[nums[i]-1]);
}
for(size_t i=0;i<n;i++) {
if(i+1!=nums[i])
return i+1;
}
return n+1;
}
};
测试用时比较玄学就不列了。
另外可以把 i+1!=nums[i] 的条件去了,不影响通过,但加上该条件更佳(避免一定重复)。
看来是while里面又带个if判断增加了时间,将前文对应代码进行修改,通过。
其他
vector<int>::size_type
::号前面是命名空间,后面是自定义的类型
要用到这个类型时,必须加上命名空间,防止和其他命名空间中的定义重复。
vector<int>::size_type ix=0
定义一个vector<int>命名空间中类型为size_type的变量ix,并将其赋值为0。