每次面试,都难免要考一些数据结构的一些算法题,尤其是对于做Java开发的程序员来说那是更加伤心,每次想跳槽都败在算法题上;所以谨以此献给Java开发人员。特别声明,这些代码很多是从网上收集来的,无意抄袭。
1、递归调用
public class Test {
public static void main(String[] args) {
while(true){
System.out.println("请输入一个正整数:");
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int result=calculateFactorial(n);
System.out.println(n+"的阶乘为:"+result);
}
}
public static int calculateFactorial(int n){
if(n==0||n==1){
return 1;
}else{
return n*calculateFactorial(n-1);
}
}
}
2、冒泡排序
(1)冒泡排序算法的运作如下:(从后往前)
-
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
-
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
-
针对所有的元素重复以上的步骤,除了最后一个。
-
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
(2)算法复杂度若文件的初始状态是正序的,一趟扫描即可完成排序。所需的关键字比较次数和记录移动次数
均达到最小值:
,
。
所以,冒泡排序最好的 时间复杂度为。
若初始文件是反序的,需要进行趟排序。每趟排序要进行
次关键字的比较(1≤i≤n-1),且每次比较都必须移动记录三次来达到交换记录位置。在这种情况下,比较和移动次数均达到最大值:
冒泡排序的最坏时间复杂度为。
综上,因此冒泡排序总的平均时间复杂度为。
算法稳定性
冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,我想你是不会再无聊地把他们俩交换一下的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。
public class Test2 {
public static void main(String[] args) {
/**
* 冒泡排序(时间复杂度O(n^2)),从小到大排序
* 1.比较相邻的元素。如果第一个比第二个大,就交换他们两个
* 2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对
* 3.针对所有的元素重复以上的步骤,除了最后一个。
* 4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较
* */
int[] a=new int[]{34,22,11,6,9,16,55};
int n=a.length;
for(int i=1;i<=n;i++){
for(int j=1;j<n-i+1;j++){
if(a[j-1]>a[j]){
int temp=a[j-1];
a[j-1]=a[j];
a[j]=temp;
}
}
}
System.out.println("排序之后的数组:");
for (int i = 0; i < n; i++) {
System.out.println(a[i]);
}
<span style="white-space:pre"> </span>}
}
3、选择排序
(1)算法原理
对比数组中前一个元素跟后一个元素的大小,如果后面的元素比前面的元素小则用一个变量k来记住他的位置,接着第二次比较,前面“后一个元素”现变成了“前一个元素”,继续跟他的“后一个元素”进行比较如果后面的元素比他要小则用变量k记住它在数组中的位置(下标),等到循环结束的时候,我们应该找到了最小的那个数的下标了,然后进行判断,如果这个元素的下标不是第一个元素的下标,就让第一个元素跟他交换一下值,这样就找到整个数组中最小的数了。然后找到数组中第二小的数,让他跟数组中第二个元素交换一下值,以此类推。
public class Test6 {
public static void main(String[] args) {
//选择排序,时间复杂度O(n^2)
int[] b=new int[]{33,22,15,3,6,18,28};
int n2=b.length;
for(int i=0;i<n2;i++){
int min=i;
for(int j=i+1;j<n2;j++){
if(b[min]>b[j]){
min=j;
}
}
if(min!=i){
int temp=b[i];
b[i]=b[min];
b[min]=temp;
}
}
System.out.println("选择排序之后:");
for (int i = 0; i < b.length; i++) {
System.out.println(b[i]);
}
}
}
4、计算两个字符串最长相同子串的长度
public class StringCompare {
/**
* 思路:
* 1、首先寻找两个字符串中第一个相同的字母,并且计数加1
* 2、如果找到第一个相同的字母后,比较两个字符串相同字母索引后的字母是否相同,相同则计数加1;不同则停止比较,进入第三部
* 3、比较计数是否比之前的大,比之前大就保存计数和相同字符串的第一个字母索引,并且把下标和计数恢复初始值。
* 4、一直循环步骤1,2,3知道循环结束
* 5、输出相同的字符串。
* */
public static void main(String[] args) {
String str1="ISANSIASPDBNJPOIJNHGF";
String str2="IOSPAOSISPDBIPOIJNIO";
char[] ch1=str1.toCharArray();
char[] ch2=str2.toCharArray();
int count=0,firstIndex=-1,max=0,tempIndex=-1;
for (int i = 0; i < ch1.length-max; i++) {
for (int j = 0; j < ch2.length-max; j++) {
if(ch1[i]==ch2[j]){
firstIndex=i;
count++;
for (int h = i+1,q=j+1; h < ch1.length&&q<ch2.length; h++,q++) {
if(ch1[h]==ch2[q]){
count++;
}else{
break;
}
}
}
if(count>max){
tempIndex=firstIndex;
max=count;
}
count=0;
firstIndex=-1;
}
}
char[] ch=new char[max];
if(tempIndex!=-1&&max>=1){
for (int i = 0; i < max; i++) {
ch[i]=ch1[tempIndex+i];
}
}
System.out.println("最长相同子串的长度为:"+max);
System.out.println("最长相同子串为:"+new String(ch));
}
}
5、用Java实现求一个字符串中连续出现次数最多的子串
运用了一个叫做后缀数组的思想。
如“abcabcbacjhkeeeehgue”,可以排列如下:
abcabcbacjhkeeeehgue
bcabcbacjhkeeeehgue
cabcbacjhkeeeehgue
abcbacjhkeeeehgue
bcbacjhkeeeehgue
cbacjhkeeeehgue
。。。
e
public class Test3 {
public static void main(String[] args) {
String str = "abcabcabcccccdefefefefefef";
int len = str.length();
int maxCount = 0;
String longest = "";
for(int pos1 = 0; pos1 < len; pos1++)
for(int pos2 = pos1 + 1; pos2 < len; pos2++){
if((2*pos2-pos1)>len){
continue;
}
if(str.substring(pos1,pos2).equals(str.substring(pos2,2*pos2-pos1))){
int offset = pos2-pos1;
int count = 2;
for(int k = pos2 + offset; k <= len; k += offset){
if((pos1+offset)>len||(k+offset)>len){
continue;
}
if(str.substring(pos1,pos1+offset).equals(str.substring(k,k+offset))){
count += 1;
}else{
break;
}
}
if(count > maxCount){
maxCount = count;
longest = str.substring(pos1,pos1+offset);
}
}
}
System.out.println("maxCount:"+maxCount+",longest:"+longest);
}
}
6、单向链表反转
单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始;链表是使用指针进行构造的列表;又称为结点列表,因为链表是由一个个结点组装起来的;其中每个结点都有指针成员变量指向列表中的下一个结点;列表是由结点构成,head指针指向第一个成为表头结点,而终止于最后一个指向nuLL的指针。
实现:
1、首先新建一个节点类Node.java
节点的特点:存储数据和指向下一个节点的指针
package com.hua.linkedlist;
/**
* @description:定义一个节点类,包括数据,和一个指针
* @date:(2015-8-12 下午10:36:17)
* @author Administrator
* @version v1.0
* @since v1.0
*
* Modified history
*
* Modified date:
* Modifier user:
* description:
*
* */
public class Node {
private int data;//数据
private Node nextNode;//下一个节点
public Node(){
}
public Node(int record){
this.data=record;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public Node getNextNode() {
return nextNode;
}
public void setNextNode(Node nextNode) {
this.nextNode = nextNode;
}
}
2、反转类ReverseSingleList.java
反转方式有两种:一种是采用递归,一种是普通的循环反转每一个节点指针。
public class ReverseSingleList {
/**
* 常规方法反转单链表
* */
public static Node reverseSingleList(Node head){
//head为头指针
if(head==null){
return null;
}
Node pre=head;
Node cur=head.getNextNode();
Node next;
while(cur!=null){
next=cur.getNextNode();
cur.setNextNode(pre);
pre=cur;
cur=next;
}
//将原链表的头结点的下一个节点的置为null,再将反转后的头结点赋给head
head.setNextNode(null);
head=pre;
return head;
}
/**
* 利用递归实现单向链表反转
* */
public static Node reverseSingleList2(Node head){
if(head==null||head.getNextNode()==null){
return head;
}
Node reversedHead =reverseSingleList2(head.getNextNode());
head.getNextNode().setNextNode(head);
head.setNextNode(null);
return reversedHead;
}
public static void main(String[] args) {
Node head=new Node(0);
Node cur=null;
Node temp=null;
//构造一个长度为10的链表,保存头结点为head
for(int i=1;i<10;i++){
temp=new Node(i);
if(i==1){
head.setNextNode(temp);
}else{
cur.setNextNode(temp);
}
cur=temp;
}
//打印反转前的链表
System.out.println("链表反转前的数据:");
Node h=head;
while(h!=null){
System.out.print(h.getData()+" ");
h=h.getNextNode();
}
//调用反转方法
System.out.println("\r\n链表反转前的数据:");
head=reverseSingleList2(head);
while(head!=null){
System.out.print(head.getData()+" ");
head=head.getNextNode();
}
}
}
最后希望大家能够把平常见到的算法题共享出来。
本文精选了Java开发中常见的算法题目,包括递归调用、冒泡排序、选择排序、字符串匹配、单链表反转等典型算法案例及其实现代码。
4737

被折叠的 条评论
为什么被折叠?



