Java面试题冲刺第二十天--手撸算法

目录
  • 手撸算法1:查找数组中重复元素和重复元素的个数
    • 1. 两层循环比较方式
    • 2. 转成Map集合处理方式
  • 手撸算法2:写个二分查找demo吧
  • 手撸算法3:把两个有序数组合并成一个有序数组
  • 总结

手撸算法1:查找数组中重复元素和重复元素的个数

当听让我写这个算法时,纸笔还没给到我手上,作为一个资深MySQL爱好者,瞬间从裤裆掏出一杆笔,打个哈欠的功夫,就在面试官脸上写下了:

select num,count(num) from T group by num order by count(num) desc;

这个问题用的是数组,两层循环比较或Map都可以解决,比较简单,但是常问;方式如下:

1. 两层循环比较方式

package com.softsec.demo;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
/**
 * 查找数组中重复元素和重复元素的个数
 * @author chenhh
 *
 */
public class getRepeat {
	/**
	 * 循环比较处理
	 * @param arr
	 */
	public static void cyclingDemo ( int[] arr){
		for (int x = 0; x < 10; x++) {
			int sumber1 = 0;
			for (int j = 0; j < 20; j++) {
				//数组中的数循环比较
				if (x == arr[j]) {
					sumber1++;
				} else {
					continue;
				}
			}
			System.out.println(x + " -- 重复个数:" + sumber1);
		}
	}
	public static void main (String[] args){
		Random random = new Random();
		int[] arr = new int[20];
		for (int i = 0; i < 20; i++) {
			arr[i] = random.nextInt(10);
			if (i < arr.length - 1) {
				System.out.print(arr[i]+",");
			} else {
				System.out.print(arr[i] + "\r\n 结果:" + "\r\n" );
			}
		}
		// 输出arr数组中重复元素,重复数量
		// 循环处理
		cyclingDemo(arr);
		// map处理
		// mapDemo(arr);
	}

打印结果:

0,3,4,0,6,5,8,1,3,1,9,3,6,3,7,5,7,1,1,1
结果:
0 -- 重复个数:2
1 -- 重复个数:5
2 -- 重复个数:0
3 -- 重复个数:4
4 -- 重复个数:1
5 -- 重复个数:2
6 -- 重复个数:2
7 -- 重复个数:2
8 -- 重复个数:1
9 -- 重复个数:1

Process finished with exit code 0

2. 转成Map集合处理方式

package com.softsec.demo;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
/**
 * 查找数组中重复元素和重复元素的个数
 * @author chenhh
 *
 */
public class getRepeat {
	/**
	 * 转成集合处理
	 * @param arr
	 */
	public static void mapDemo ( int[] arr){
		//将数据转成集合
		Map<Integer, Integer> map = new HashMap();
		for (int a = 0; a < arr.length; a++) {
			if (map.get(arr[a])!=null){
				map.put(arr[a],map.get(arr[a])+1);
			}
			else {
				map.put(arr[a],1);
			}
		}
		for (int i = 0; i <10 ; i++) {
			System.out.println(i + " -- 重复个数:" + map.get(i));
		}
	}
}

	public static void main (String[] args){
		Random random = new Random();
		int[] arr = new int[20];
		for (int i = 0; i < 20; i++) {
			arr[i] = random.nextInt(10);
			if (i < arr.length - 1) {
				System.out.print(arr[i]+",");
			} else {
				System.out.print(arr[i] + "\r\n 结果:" + "\r\n" );
			}
		}
		// 输出arr数组中重复元素,重复数量
		// 循环处理
		// cyclingDemo(arr);
		// map处理
		mapDemo(arr);
	}
}

打印结果:

2,2,7,7,1,6,1,7,1,9,1,2,1,9,9,4,0,3,5,1
结果:
0 -- 重复个数:1
1 -- 重复个数:6
2 -- 重复个数:3
3 -- 重复个数:1
4 -- 重复个数:1
5 -- 重复个数:1
6 -- 重复个数:1
7 -- 重复个数:3
8 -- 重复个数:null
9 -- 重复个数:3

Process finished with exit code 0

手撸算法2:写个二分查找demo吧

二分查找的条件是对一组有序数组的查找,所以要先确定查找的数组是否有序,在使用二分查找的时候先要对数组进行排序。

加个排序多麻烦?所以面试官不指定无序数组时,就都当有序的就行。无序你用什么二分法是吧?

二分算法步骤

1.首先确定整个查找区间的中间位置mid = ( left + right )/ 2

2.用待查关键字值与中间位置的关键字值进行比较;

★ 若相等,则查找成功

★ 若大于,则在后(右)半个区域继续进行折半查找

★ 若小于,则在前(左)半个区域继续进行折半查找

3.对确定的缩小区域再按折半公式,重复上述步骤,使用递归或普通while循环都可以。

这里我们对给定数列(有序){ 1, 20, 23, 24, 35, 46, 77, 78, 99, 100},通过二分法查找值为78的数据元素。

package com.softsec.demo;
/**
 * 二分查找算法,两种方法,一种递归一种非递归
 * @author chenhh
 *
 */
public class BinaryQry {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] arr = new int[] { 1, 20, 23, 24, 35, 46, 77, 78, 99, 100 };
		int index = search(arr,0,arr.length-1,78);
		//int index = search2(arr, 11);
		if (index == -1) {
			System.out.println("没找到");
			return;
		}
		System.out.println("在数组的第" + (index+1) + "位");
	}
	/*
	 * 递归方法查找
	 */
	public static int search(int[] arr, int left, int right, int key) {
		if (left <= right) {
			int mid = (left + right) / 2;
			if (key < arr[mid]) {
				return search(arr, left, mid - 1, key);
			} else if (key > arr[mid]) {
				return search(arr, mid + 1, right, key);
			} else {
				return mid;
			}
		}
		return -1;
	}
	/*
	 * 非递归方法查找
	 */
	public static int search2(int[] arr, int key) {
		int left = 0;
		int right = arr.length - 1;
		int mid = 0;
		while (left <= right) {
			mid = (left + right) / 2;
			if (key == arr[mid]) {
				return mid;
			} else if (key > arr[mid]) {
				left = mid + 1;
			} else if (key < arr[mid]) {
				right = mid - 1;
			}
		}
		return -1;
	}
}

手撸算法3:把两个有序数组合并成一个有序数组

对于两个有序数组arrayM,arrayN,数组长度分别为m和n;

思路:

  • 定义一个新数组newArray,长度为m+n;
  • 定义两个index(int),如:int start=0,end=0,用来记录数组arrayM、arrayN的下标;
  • 通过分别遍历数组arrayM和arrayN的方式来比较每个值的大小,并将值存放到newArray中;
  • 判断start和end是否分别小于m和n,如果小于则继续执行,否则则表示有一个array遍历结束,然后将另一个array剩余部分追加到newArray中即可;
package com.softsec.demo;
/**
 * 两个有序数组合并成一个有序数组的实现类
 * @author chenhh
 *
 */
public class ArrayMerge {
	/**
	* 数组合并方法
	* @param arrayM
	* @param arrayN
	* @return
	*/
	public static int[] mergeArray(int arrayM[],int arrayN[]){
		int newArray[];
		// 定义一个新数组,长度为两个有序数组长度之和
		newArray = new int[arrayM.length + arrayN.length];
		// start:arrayM数组下标    end:arrayN数组下标  k:newArray新数组下标
		int start=0,end=0,k=0;
		// 循环比较两个数组,较小元素的放入新数组,较小元素所在数组下标加一,较大元素对应的数组下标不加一,直到某一个下标等于数组长度时退出循环
		while(start<arrayM.length && end<arrayN.length) {
			if(arrayM[start] <= arrayN[end]) {
				newArray[k++] = arrayM[start++];
			}else{
				newArray[k++] = arrayN[end++];
			}
		}
		/* 后面两个while循环是用来保证两个数组比较完之后剩下的一个数组里的元素能顺利都放入新数组
		* 此时较短数组已经全部放入新数组,较长数组还有部分剩余,最后将剩下的部分元素放入新数组,因为数组是有序,所以直接把剩下的顺序加入即可*/
		while(start < arrayM.length) {
			newArray[k++] = arrayM[start++];
		}
		while(end < arrayN.length) {
			newArray[k++] = arrayN[end++];
		}
		return newArray;
	}
	/**
	* 数组打印方法
	* @param arr
	*/
	public static void print(int[] arr) {
		for(int i=0; i<arr.length;i++) {
			if (i < arr.length -1) {
				System.out.print(arr[i]+",");
			} else {
				System.out.print(arr[i]);
			}
		}
	}
	public static void main(String[] args) {
		int[] arrayM = {1,3,5,7,8,9,14,16,21};
		int[] arrayN = {0,10,20,30,40,50};
		print(mergeArray(arrayM,arrayN));
	}
}

结果打印:

0,1,3,5,7,8,9,10,14,16,20,21,30,40,50
Process finished with exit code 0

总结

本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • Java面试题冲刺第十五天--设计模式

    目录 面试题1:面向对象程序设计(OOP)的六大原则分别有哪几个 面试题2:你说一下什么是设计模式 追问1:那你怎么理解高内聚和低耦合? 面试题3:设计模式有哪几种? 追问1:你比较熟悉哪种设计模式?说说原理. 追问2:那你说说适配器模式的原理吧 适配器模式优缺点 总结 面试题1:面向对象程序设计(OOP)的六大原则分别有哪几个 开闭原则(Open Close Principle)及"开放-封闭原则"单一职责原则(Single Responsibility Principle)里氏替换

  • Java面试题冲刺第十六天--消息队列

    目录 面试题1:说说你对消息队列的理解,消息队列为了解决什么问题? 解耦 异步 削峰 追问1:消息队列有什么优缺点 面试题2:对于消息中间机,你们是怎么做技术选型的? 面试题3:如何确保消息正确地发送至 RabbitMQ?如何确保消息接收方消费了消息? 发送方确认模式 接收方确认机制 追问1:如何保证MQ消息的可靠传输? 总结 面试题1:说说你对消息队列的理解,消息队列为了解决什么问题? 我们公司业务系统一开始体量较小,很多组件都是单机版就足够,后来随着用户量逐渐扩大,我们程序也采用了微服务的设

  • Java面试题冲刺第十八天--Spring框架3

    面试题1:Bean 的加载过程是怎样的? 我们知道, Spring 的工作流主要包括以下两个环节: 解析,读 xml 配置,扫描类文件,从配置或者注解中获取 Bean 的定义信息,注册一些扩展功能. 加载,通过解析完的定义信息获取 Bean 实例. 下面是跟踪了 getBean的调用链创建的流程图,为了能够很好地理解 Bean 加载流程,省略一些异常.日志和分支处理和一些特殊条件的判断. 从上面的流程图中,可以看到一个 Bean 加载主要会经历这么几个阶段(标绿内容): 获取 BeanName,

  • Java面试题冲刺第十九天--数据库(4)

    目录 面试题1:说一下你对聚集索引与非聚集索引的理解,以及他们的区别? 1.聚集索引 2.非聚集索引 追问1:为什么聚集索引可以创建在任何一列上,如果此表没有主键约束,即有可能存在重复行数据呢? 追问2:聚集索引一定比非聚集索引性能优么? 面试题2:说一说你对 B树 和 B+树 的理解吧 1.B树(Balanced Tree)多路平衡查找树 多叉 2.B+ Tree (B+树是B树的变体,也是一种多路搜索树) 面试题3:说一下你对最左前缀原则的理解吧 一.最左匹配原则的原理 二.违背最左原则导致

  • Java面试题冲刺第十四天--基础篇3

    目录 面试题1:JDK1.8的新特性有哪些? 接口的默认和静态方法: Lambda 表达式: 方法与构造函数引用: 函数式接口: Annotation 注解:支持多重注解: 新的日期时间 API: Base64编码: JavaScript引擎Nashorn: Stream的使用: Optional: 扩展注解的支持: 并行(parallel)数组: 编译器优化: 其他核心 API 的改进 Java IO改进 集合 API 的改进 面试题2:什么是内部类?内部类的作用? 内部类的作用 内部类特点

  • Java面试题冲刺第二十天--手撸算法

    目录 手撸算法1:查找数组中重复元素和重复元素的个数 1. 两层循环比较方式 2. 转成Map集合处理方式 手撸算法2:写个二分查找demo吧 手撸算法3:把两个有序数组合并成一个有序数组 总结 手撸算法1:查找数组中重复元素和重复元素的个数 当听让我写这个算法时,纸笔还没给到我手上,作为一个资深MySQL爱好者,瞬间从裤裆掏出一杆笔,打个哈欠的功夫,就在面试官脸上写下了: select num,count(num) from T group by num order by count(num)

  • Java面试题冲刺第二十天--算法(1)

    目录 手撸算法1:查找数组中重复元素和重复元素的个数 1. 两层循环比较方式 2. 转成Map集合处理方式 手撸算法2:写个二分查找demo吧 手撸算法3:把两个有序数组合并成一个有序数组 总结 手撸算法1:查找数组中重复元素和重复元素的个数 当听让我写这个算法时,纸笔还没给到我手上,作为一个资深MySQL爱好者,瞬间从裤裆掏出一杆笔,打个哈欠的功夫,就在面试官脸上写下了: select num,count(num) from T group by num order by count(num)

  • Java面试题冲刺第二十三天--算法(2)

    目录 面试题1:你说一下常用的排序算法都有哪些? 追问1:谈一谈你对快排的理解吧 追问2:说一下快排的算法原理 追问3:来吧!给我手敲一个快排 面试题2:来!再给我手撸一个Spring 追问1:哦,咳咳-说一下构成递归的前提条件有啥? 追问2:递归都有哪些优缺点? 追问3:给我手写一个简单的递归算法的实现吧 面试题3: 10亿个数中找出最大的100000个数(top K问题) 总结 面试题1:你说一下常用的排序算法都有哪些? 追问1:谈一谈你对快排的理解吧 快速排序,顾名思义就是一种以效率快为特

  • Java面试题冲刺第五天--基础篇2

    目录 面试题1:说一下抽象类和接口有哪些区别? 正经回答: 深入追问: 追问1:说一说你对抽象类的理解吧,他到底是干啥用的 追问2:用抽象类实现一个接口,和普通类实现接口会有什么不同么? 追问3:抽象类能使用 final 修饰吗? 面试题2:final 在 Java 中有什么作用? 正经回答: 1.修饰类 2.修饰方法 3.修饰变量 深入追问: 追问1:能分别说一下final.finally.finalize的区别么? 面试题3:你对Java序列化了解么? 正经回答: 深入追问: 追问1:Jav

  • Java面试题冲刺第一天--基础篇1

    目录 面试题1:Java 中操作字符串都有哪些类?它们之间有什么区别? 正经回答: 深入追问: 追问1:这三者在效率上怎么说? 追问2:那StringBuffer和StringBuffer线程安全主要差在哪里呢? 面试题2:请你说一下Error 和 Exception 区别是什么? 正经回答: 面试题3:== 和 equals 的区别是什么 正经回答: 深入追问: 追问1:如果我们不重写equals() 方法,会怎么样? 追问2:重写equals的同时,我们需要重写hashCode()方法么?为

  • Java面试题冲刺第九天--MyBatis2

    目录 面试题1:说说你对Mybatis的理解? 追问1:说一下MyBatis的工作原理和流程吧. 追问2:列举几个MyBatis的核心组件,说说分别干啥用? 面试题2:(问几个实际使用的问题)Mybatis动态sql是做什么的?都有哪些动态sql? 追问1:Xml映射文件中,除了常见的select|insert|updae|delete标签之外,你还常用哪些标签? 追问2:Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式? 追问3:MyBatis中接口绑定你都用过哪几

  • Java面试题冲刺第九天--MyBatis

    目录 面试题1:你怎么理解ORM框架,常见的ORM框架都有哪些? 正经回答: 追问1:大家都在用Mybatis,Mybatis都有哪些优势? 面试题2:相比较Hibernate与Mybatis,你有哪些看法? 正经回答: 面试题3:Mybatis中的#{}和${}有哪些区别 正经回答: 深入追问: 追问1:什么是sql注入? 追问2:mybatis是如何做到防止sql注入的? 总结 面试题1:你怎么理解ORM框架,常见的ORM框架都有哪些? 正经回答: 对象关系映射(Object Relatio

  • Java面试题冲刺第八天--Spring框架2

    目录 面试题1:聊一下你对AOP的理解吧? 追问1:Advice通知的类型有哪几种? 追问2:在同一个切面(Aspect)中,不同Advice的执行顺序 面试题2:AspectJ AOP 和 Spring AOP 有什么区别? 追问1:了解JDK动态代理和CGLIB动态代理的原理么?他俩有哪些区别? 面试题3:什么是基于Java的Spring注解配置? 给一些注解的例子 总结 面试题1:聊一下你对AOP的理解吧? AOP(Aspect Oriented Programming),面向切面思想,是

  • Java面试题冲刺第七天--Spring框架1

    目录 面试题1:能简单说一下你对Spring框架的理解么? 追问1:常见的Core组件有哪些? 面试题2:谈谈对Spring IOC的理解 追问1:Spring中的bean的作用域有哪些? 追问2:Spring中的bean生命周期? 追问3: Spring 中的 bean 是线程安全的吗? 面试题3:说一下 SpringMVC 运行流程? 追问1:能介绍一下SpringMVC各组件的作用么? 总结 面试题1:能简单说一下你对Spring框架的理解么? 我们一般说的Spring框架就是Spring

  • Java面试题冲刺第十一天--集合框架篇(2)

    目录 面试题1:说一下 HashMap 的实现原理? 正经回答: 深入追问: 追问1:如何实现HashMap的有序? 追问2:那TreeMap怎么实现有序的? 追问3:put方法原理是怎么实现的? 追问4:HashMap扩容机制原理 追问5:HashMap在JDK1.8都做了哪些优化? 追问6:链表红黑树如何互相转换?阈值多少? 面试题2:HashMap是线程安全的吗? 正经回答: 追问1:你是如何解决这个线程不安全问题的? 总结 面试题1:说一下 HashMap 的实现原理? 正经回答: 众所

随机推荐