第一种解法:原地哈希
看了官方题解的结果。和之前两道题思路相似,但进行了一些数据处理,如将负数化为len+1来避免干扰,让出负号打标。第二遍遍历检查标识。
class Solution {
public int firstMissingPositive(int[] nums) {
//出现的话,打标。
int len = nums.length;
for(int i = 0;i< len;i++){//
if(nums[i] <= 0){
nums[i] = len+1;
}
}
for(int num: nums){
if(Math.abs(num) > 0 && Math.abs(num) <= len && nums[Math.abs(num)-1] > 0){
nums[Math.abs(num)-1] = -nums[Math.abs(num)-1];//打标
}
}
for(int i = 0;i< len;i++){
if(nums[i] >= 0){
return i+1;
}
}
return len + 1;
}
}
第二种解法:置换
将数据置换到该去的位置上,和之前的思路相似
class Solution {
public int firstMissingPositive(int[] nums) {
int n = nums.length;
for (int i = 0; i < n; ++i) {
while (nums[i] > 0 && nums[i] <= n && nums[nums[i] - 1] != nums[i]) {
int temp = nums[nums[i] - 1];
nums[nums[i] - 1] = nums[i];
nums[i] = temp;
}
}
for (int i = 0; i < n; ++i) {
if (nums[i] != i + 1) {
return i + 1;
}
}
return n + 1;
}
}
作者:力扣官方题解
链接:https://leetcode.cn/problems/first-missing-positive/solutions/304743/que-shi-de-di-yi-ge-zheng-shu-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
碎碎念:
第一次做hard题,结构化刷题的好处显露出来,可以马上进行实践。这里hard的限制似乎是对数据的夸张化和复杂度的要求,感觉很刁钻,即见过类似的题、知道数据结构的话并不难,不知道的话就很难想。
- 加重了对各种数据结构的思考(看一些题解的时候也开始思考HashSet,之前没有接触过这个)
- 对哈希快速搜索的敏感度精进了些。
- 猜测置换和原地哈希在这类题功用是可以互相替换的,前者是一种方法,后者是抽象灵活地实现一种数据结构。
- 对数据处理能力增强,主要是明白了简化题干、只寻找和关注与题干有关的数据(如这里的1-N)。
- 感觉到了结构化刷题的优势。非常、非常感谢整理刷题类别和顺序的佬们
- 增加了信心···
反思:现在刷题的速度还是太慢了,而且基础数据结构了解不足,感觉需要抽时间去了解一下基础数据结构和基础算法(如排序),实现手搓来加深印象。也准备看一些书了