LeetCode刷题(八)-----数组-------easy部分(Java、C++)
414. 第三大的数
给定一个非空数组,返回此数组中第三大的数。如果不存在,则返回数组中最大的数。要求算法时间复杂度必须是O(n)。
思路一:
方法1:用set,代码简单但是好慢
思路二:
遍历数组维护最大的三个数。
基本思路:
遍历数组:
如果比第一个数大,第一第二移动到第二第三,更新第一。
如果比第二个数大,第二移动到第三,更新第二。
如果比第三个数大,更新第三。
难点是三个数怎么初始化,因为可能存在最小值。所以不能将三个数初始化为最小值。
这里解决的方法是使用vector,利用vector的大小来判断。
只有一种情况下需要向vector中添加元素,就是nums[i]比vector中所以数都小,并vector.size小于3
!在这里插入图片描述
作者:can-he-VRFM7JwrhT
链接
448. 找到所有数组中消失的数字
给定一个范围在1 ≤ a[i] ≤ n (n = 数组大小)的整型数组,数组中的元素一些出现了两次,另一些只出现一次。
找到所有在 [1, n] 范围之间没有出现在数组中的数字。
您能在不使用额外空间且时间复杂度为O(n)的情况下完成这个任务吗? 你可以假定返回的数组不算在额外空间内。
思路一:C++
1.桶排序,时间复杂度为 O(n),可以把出现了的数字放在正确的位置。
2.为了避免转换下标的麻烦,在末尾插入一个0,排序后0会出现在首位。
[4,3,2,7,8,2,3,1,0] 会被排序为 [0,1,2,3,4,2,3,7,8]
3.然后把不等于值的索引返回。
思路二:
1.将数组元素对应为索引的位置加n
2.遍历加n后的数组,若数组元素值小于等于n,则说明数组下标值不存在,即消失的数字
思路三:鸽巢思想 两种方式 逐行解释 python3
第一时间想到一个萝卜一个坑,鸽巢思想。
鸽巢思想
对于题目中1<=nums[i]<=n,我们只需将每个数字放到正确的位置上(对应的下标)。再遍历一次数组,那么位置上不是对应的数时,即为缺失的数字
1.遍历数组,对于nums[i]:
循环条件,若nums[i]!=i+1并且nums[i]!=nums[nums[i]-1]。意思是若当前位置的元素不等于i+1,将它放到对应的下标nums[i]-1处。为了避免死循环,若正确的位置上已经有了正确的元素,则结束。
2.遍历排序后的数组,若位置上不是正确的元素,则加入res
复杂度分析
• 时间复杂度:O(n)
• 空间复杂度:O(1)
Python
作者:zhu_shi_fu
链接:https://leetcode-cn.com/problems/find-all-numbers-disappeared-in-an-array/solution/ge-chao-si-xiang-liang-chong-fang-shi-zhu-xing-jie/
我的:
class Solution {
public:
vector<int> findDisappearedNumbers(vector<int>& nums)
{
nums.push_back(0);
for(int i=0;i<nums.size();++i)
while(nums[i]!=nums[nums[i]])
swap(nums[i],nums[nums[i]]);
vector<int> ans;
for(int i=1;i<nums.size();++i)
if(i!=nums[i])
ans.push_back(i);
return ans;
}
};