剑指offer——3.实现数组中重复数字查找

本文介绍了在数组中查找重复数字的三种主要方法:通过排序并比较相邻元素,利用数组元素交换特性,以及使用辅助数组进行查找。每种方法都有其独特的实现方式和适用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

知识点:

  1. 排序一个长度为n的数组需要\mathit{O}(nlogn)的时间
  2. 变量和属性的区别:
    1. 变量是方法体中定义的,我们称为临时变量;属性是类体中定义的。
    2. 权限标示符只用于修饰属性和方法。不修饰变量。
    3. 方法中定义的临时变量在方法调用完成之后就不存在了,不需要用修饰符定义!

注意:

  1. 写代码之前,先将输入的范围固定

代码实现:

  • 先将数组排序,比对数组前后的数值是否相同
/**
	 * 题1:找出数组中重复的数字
	 * 方法1:先排序;再比对数组前后的数值是否相同
	 */
private static boolean findNum1(int[] ars) {
    //将a数组排序
    Arrays.sort(ars);
    //比对数组中前后的数是否相同
    for(int i=0; i<ars.length-1; i++) {
	if(ars[i]==ars[i+1]) {
	    return true;
	}
    }
    return false;
}
  • 先判断数组下标i与对应数组的值arr[i]是否相同;若相同继续判断下一位;
  • 若不同,先判断arr[i]与arr[arr[i]]是否相同,若不同,交换位置,至arr[i]与i相同
/**
	 * 方法2:先判断ars下标i与ars[i]是否相同;
	 * 若不同,进行交换;
	 * 交换之前,判断交换的2数是否相同; 
	 */
private static boolean findNum2(int[] ars) {
	if(ars==null||ars.length<=0) {
		return false;
	}
	
	for(int i:ars) {
		if(i<0||i>ars.length-1) {
			return false;
		}
	}
	
	for(int i=0;i<ars.length; i++) {
		//如果i与ars[i]不等
		while(ars[i]!=i) {
			//判断是否相等
			if(ars[i]==ars[ars[i]]) {
				return true;
			}
			//进行交换
			int tmp = ars[i];
			ars[i] = ars[tmp];
			ars[tmp] = tmp;
		}
	}
	return false;
  • 不修改数组找出重复数字—— 借助辅助数组
/**
	  * 题2不修改数组找出重复的数字
	  * 法1:复制至一个辅助数组,如原数组中被复制的数为2,则复制到下标为2的位置
	  */
	 private static boolean findNum3(int[] ars) {
		 int [] newArray = new int[ars.length];
		 for(int i:ars) {
			 newArray[i]=-1;
		 }
		 for(int j=0; j<ars.length; j++) {
			 if(newArray[ars[j]]==ars[j]) {
				 return true;
			 }else {
				 newArray[ars[j]]=ars[j];
			 }
		 }
		 return false;
	 }
  • 不修改数组找出重复数字—— 类二分查找
 /**
	  * 题2不修改数组找出重复的数字
	  * 法2:二分查找法:先分两半,比较前一半数字的数目和与前一半数字的个数;
	  * 若大于,则说明有重复,在前一半数字中再进行分两半;若小于,则说明后一半有重复;
	  */
	 private static int findNum4(int[] ars) {
		 if(ars==null||ars.length<=0) {
				return -1;
			}
			
			
		 int start=0;
		 int end=ars.length-1;
		 while(end>=start) {
			 //找中间数
			 int mid = (end - start)/2+start;
			 //比较前一部分数的个数和与前一部分的个数
			 int count = total(ars, start, mid);
			 //若迭代至一个数,且它的个数还大于1,输出这个数
			 if(start== end) {
				 if(count>1) {
					 System.out.println(start);
					 break;
				 }else {
					 break;
				 }
			 }
			 if(mid-start+1<count) {
				 end = mid;
			 }else {
				 start = mid+1;
			 }
		 }
		 return -1;
	 }

	private static int total(int[] ars, int start, int end) {
		int count =0;
		for(int i=0; i<ars.length; i++) {
			if(ars[i]>=start && ars[i]<=end) {
				count++;
			}
		}
		return count;
	}

 

标题“51单片机通过MPU6050-DMP获取姿态角例程”解析 “51单片机通过MPU6050-DMP获取姿态角例程”是一个基于51系列单片机(一种常见的8位微控制器)的程序示例,用于读取MPU6050传感器的数据,并通过其内置的数字运动处理器(DMP)计算设备的姿态角(如倾斜角度、旋转角度等)。MPU6050是一款集成三轴加速度计和三轴陀螺仪的六自由度传感器,广泛应用于运动控制和姿态检测领域。该例程利用MPU6050的DMP功能,由DMP处理复杂的运动学算法,例如姿态融合,将加速度计和陀螺仪的数据进行整合,从而提供稳定且实时的姿态估计,减轻主控MCU的计算负担。最终,姿态角数据通过LCD1602显示屏以字符形式可视化展示,为用户提供直观的反馈。 从标签“51单片机 6050”可知,该项目主要涉及51单片机和MPU6050传感器这两个关键硬件组件。51单片机基于8051内核,因编程简单、成本低而被广泛应用;MPU6050作为惯性测量单元(IMU),可测量设备的线性和角速度。文件名“51-DMP-NET”可能表示这是一个与51单片机及DMP相关的网络资源或代码库,其中可能包含C语言等适合51单片机的编程语言的源代码、配置文件、用户手册、示例程序,以及可能的调试工具或IDE项目文件。 实现该项目需以下步骤:首先是硬件连接,将51单片机与MPU6050通过I2C接口正确连接,同时将LCD1602连接到51单片机的串行数据线和控制线上;接着是初始化设置,配置51单片机的I/O端口,初始化I2C通信协议,设置MPU6050的工作模式和数据输出速率;然后是DMP配置,启用MPU6050的DMP功能,加载预编译的DMP固件,并设置DMP输出数据的中断;之后是数据读取,通过中断服务程序从DMP接收姿态角数据,数据通常以四元数或欧拉角形式呈现;再接着是数据显示,将姿态角数据转换为可读的度数格
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值