【LeetCode 0-Start】[数组]统计数组中的元素

【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;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值