【LeetCode 0-Start】[数组]统计数组中的元素
文章目录
前言
统计数组中的元素
题目序号: 645、697、448、442、41、274
一、[简单]645. 错误的集合
题目来源
算法思想:数组;
java代码
class Solution {
public int[] findErrorNums(int[] nums) {
boolean[] m = new boolean[nums.length+1];//记录1~N数字,全为false
int[] res = new int[2];//返回{重复数字,缺少数字}
for (int i = 0; i < nums.length; i++) {
if(m[nums[i]] == false) {//如果没有被访问过
m[nums[i]] = true;//记为访问
}
else {//被访问过,即出现重复
res[0] = nums[i];//将重复数字,记录下来
}
}
//访问标记数组m
for (int i = 1; i < m.length; i++) {
if (m[i] == false) {//找到没有被访问过的,即缺少的数字
res[1] = i;//将缺少数字,记录下来
}
}
return res;
}
}
二、[简单]697. 数组的度
题目来源
算法思想:数组,map;
PS:map的使用,entry遍历
//图map的遍历
for(Entry<Integer, Integer> entry : map.entrySet()){
entry.getValue();//获取值
entry.getKey();//获取键
}
java代码
import java.util.Map.Entry;
//推荐使用map.entry遍历哈希表,效率高
//使用map.entry遍历是,记得导入包,leetcode
class Solution {
public int findShortestSubArray(int[] nums) {
Map<Integer, Integer> count = new HashMap();
Map<Integer, Integer> left = new HashMap();
Map<Integer, Integer> right = new HashMap();
for (int i = 0; i < nums.length; i++) {
int x = nums[i];
//第一次遍历,记录左边
if(left.get(x) == null) {
left.put(x, i);
count.put(x, 1);
}
//第二次遇见,重复的数值,记录右边,统计出现次数
else {
count.put(x, count.get(x)+1);
}
//第二次遇见,重复的数值,记录右边,统计出现次数
right.put(x, i);//每一次都要赋值,[1]时,不会right.get(x)-left.get(x)+1出错
}
int len = nums.length;
//得到,count哈希表中values最大值
//Collections的min.max方法:返回集合中的最小值,最大值
//count.values(),获取count中values集合
int degree = Collections.max(count.values());
//遍历count,计算符合度的right.get(x)-left.get(x)+1最小值
for(Entry<Integer, Integer> entry : count.entrySet()){
if (entry.getValue() == degree) {
int x = entry.getKey();
len = Math.min(len, right.get(x)-left.get(x)+1);
}
}
return len;
}
}
三、[简单]448. 找到所有数组中消失的数字
题目来源
算法思想:数组;
java代码
public List<Integer> findDisappearedNumbers(int[] nums) {
List<Integer> res = new ArrayList<Integer>();
boolean[] falg = new boolean[nums.length+1];//用来标志数字
for (int i = 0; i < nums.length; i++) {
if (falg[nums[i]] == false) {
falg[nums[i]] = true;
}
}//先遍历,将已经有的数字标志为true
for (int i = 1; i < falg.length; i++) {
if(falg[i] == false) {
res.add(i);//将不存在的数字存入最后答案
}
}
return res;
}
提升–不使用额外空间,O(n)的解法
public List<Integer> findDisappearedNumbers(int[] nums) {
List<Integer> res = new ArrayList<Integer>();
//如果x数值存在,则nums[x-1]中的值将变成负数,以此来区别
for (int i = 0; i < nums.length; i++) {
//取绝对值,因为部分数可能被改成了负数
int x = Math.abs(nums[i]);
if(nums[x-1] > 0){//如果当前x没有被标记.则将其nums[x-1]修改成负数
nums[x-1] = nums[x-1] * (-1);
}
}
//遍历,其中nums[i] > 0,则i+1表示的数不存在,将其存入res
for (int i = 0; i < nums.length; i++) {
if(nums[i] > 0) {
res.add(i+1);
}
}
return res;
}
四、[中等]442. 数组中重复的数据
题目来源
算法思想:数组;
java代码
class Solution {
public List<Integer> findDuplicates(int[] nums) {
List<Integer> res = new ArrayList<Integer>();
int[] falg = new int[nums.length+1];//用来统计数字出现的频率
for (int i = 0; i < nums.length; i++) {
falg[nums[i]]++;
}
for (int i = 1; i < falg.length; i++) {
if(falg[i] == 2) {//将频率为2的数,存入答案
res.add(i);//将不存在的数字存入最后答案
}
}
return res;
}
}
五、[困难]41. 缺失的第一个正数
题目来源
算法思想:数组;数组自标记
思路:
1.遍历一次数组把大于等于1的和小于数组大小的值放到原数组对应位置(将a数值,交换放入a-1的位置)
2.然后再遍历一次数组查当前下标是否和值对应(nums[a] == a+1),如果不对应那这个下标就是答案,否则遍历完都没出现那么答案就是数组长度加1。
java代码O(n)
class Solution {
public int firstMissingPositive(int[] nums) {
int i = 0;
//交换阶段,{3,2,1,4},即将1放入下标0位置,2放入下标1位置
while(i < nums.length) {
//(nums[i] > 0 && nums[i] < nums.length:寻找正整数,进行交换,范围为1~nums.length
//nums[nums[i]-1] != nums[i]:如果待交换的(3下标放得2,正解)这样的情形,不进行交换,i++;
if(nums[i] > 0 && nums[i] < nums.length && nums[nums[i]-1] != nums[i]) {
int a = nums[i];
nums[i] = nums[a-1];
nums[a-1] = a;
}
else {
i++;
}
}
//交换结束数组为{1,2,3,4}
//遍历交换后的数组,如果nums[j] == j+1,即正整数j+1存在,则index+1,
int index = 0;
for (int j = 0; j < nums.length; j++) {
if(nums[j] == j+1) {
index = j+1;
}
else {//一旦nums[j] != j+1,停止遍历,意味着有缺失整数
break;
}
}
//循环结束,最后记录的正整数是index,index+1表示缺失的正整数
return index+1;
}
}
六、[中等]274. H 指数
题目来源
算法思想:数组;
思路:
1.数组排序;
2.找到最小的i,使得nums[i] >= length-i+1; 即有ength-i+1篇文章,最少引用数量nums[i],两者满足nums[i] >= length-i+1,
某人的 h 指数是 20,这表示他已发表的论文中,每篇被引用了至少 20 次的论文总共有 20 篇。
时间复杂度O(nlogn)
java代码
public int hIndex(int[] citations) {
Arrays.sort(citations);//排序,升序
int h = citations.length;//最少文章数量
for (int i = 0; i < citations.length; i++) {
if(citations[i] >= h) {
return h;
}
else {
h--;
}
}
return h;
}