个最常见的Java算法.docx

上传人:b****4 文档编号:11866567 上传时间:2023-04-06 格式:DOCX 页数:13 大小:20.41KB
下载 相关 举报
个最常见的Java算法.docx_第1页
第1页 / 共13页
个最常见的Java算法.docx_第2页
第2页 / 共13页
个最常见的Java算法.docx_第3页
第3页 / 共13页
个最常见的Java算法.docx_第4页
第4页 / 共13页
个最常见的Java算法.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

个最常见的Java算法.docx

《个最常见的Java算法.docx》由会员分享,可在线阅读,更多相关《个最常见的Java算法.docx(13页珍藏版)》请在冰豆网上搜索。

个最常见的Java算法.docx

个最常见的Java算法

代码面试最常用的10大算法

发表于2018-04-1011:

34|16225次阅读|来源ProgramCreek|279条评论|作者XWang

Java面试算法排序二叉树归并排序职业生涯

摘要:

面试也是一门学问,在面试之前做好充分的准备则是成功的必须条件,而程序员在代码面试时,常会遇到编写算法的相关问题,比如排序、二叉树遍历等等。

在程序员的职业生涯中,算法亦算是一门基础课程,尤其是在面试的时候,很多公司都会让程序员编写一些算法实例,例如快速排序、二叉树查找等等。

本文总结了程序员在代码面试中最常遇到的10大算法类型,想要真正了解这些算法的原

理,还需程序员们花些功夫。

1.String/Array/Matrix

在Java中,String是一个包含char数组和其它字段、方法的类。

如果没有IDE自动完成

代码,下面这个方法大家应该记住:

toCharArray(>//getchararrayofaString

Arrays.sort(>//sortanarray

Arrays.toString(char[]a>//converttostring

charAt(intx>//getacharatthespecificindex

length(>//stringlength

length//arraysize

substring(intbeginIndex>

substring(intbeginIndex,intendlndex>

Integer.valueOf(>//stringtointeger

String.valueOf(>/integertostring

String/arrays很容易理解,但与它们有关的问题常常需要高级的算法去解决,例如动态编程、递归等。

下面列出一些需要高级算法才能解决的经典问题:

EvaluateReversePolishNotationLongestPalindromicSubstring单词分割

字梯

MedianofTwoSortedArrays

正则表达式匹配

合并间隔

插入间隔

TwoSum

3Sum

4Sum

3SumClosest

StringtoInteger

合并排序数组

ValidParentheses实现strStr(>

SetMatrixZeroes

搜索插入位置

LongestConsecutiveSequenee

ValidPalindrome

螺旋矩阵

搜索一个二维矩阵

旋转图像

三角形

DistinctSubsequencesTotalMaximumSubarray

删除重复的排序数组

删除重复的排序数组2查找没有重复的最长子串包含两个独特字符的最长子串

PalindromePartitioning

2.链表

在Java中实现链表是非常简单的,每个节点都有一个值,然后把它链接到下一个节点。

classNode{

intvalo

Nodenext。

Node(intx>{

val=xo

next=null。

}

}

比较流行的两个链表例子就是栈和队列。

classStack{

NodetopopublicNodepeek(>{

if(top!

=null>{

returntop。

}returnnull

}publicNodepop(>{

if(top==null>{

returnnull。

}else{

Nodetemp=newNode(top.val>。

top=top.next。

returntemp。

}

}

publicvoidpush(Noden>{

if(n!

=null>{

n.next=top。

top=n。

}

}

}

队列

classQueue{

Nodefirst,last。

 。

publicvoidenqueue(Noden>{if(first==null>{

first=n。

last=first

}else{

last.next=n。

last=n。

}

}

 。

publicNodedequeue(>{

if(first==null>{

returnnull。

}else{

Nodetemp=newNode(first.val>

first=first.next。

returntemp。

}

}

}

值得一提的是,Java标准库中已经包含一个叫做Stack的类,链表也可以作为一个队列使

用<add(>和remove(>)。

<链表实现队列接口)如果你在面试过程中,需要用到栈或队列解决问题时,你可以直接使用它们。

在实际中,需要用到链表的算法有:

*插入两个数字

*重新排序列表

*链表周期

«CopyListwithRandomPointer

«合并两个有序列表

•合并多个排序列表

•从排序列表中删除重复的

«分区列表

•LRU缓存

3•树&堆

这里的树通常是指二叉树。

classTreeNode{

intvalue。

TreeNodeleft。

TreeNoderight。

}

下面是一些与二叉树有关的概念:

*二叉树搜索:

对于所有节点,顺序是:

leftchildren<=currentnode<=right

children;

*平衡vs.非平衡:

它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,

并且左右两个子树都是一棵平衡二叉树;

*满二叉树:

除最后一层无任何子节点外,每一层上的所有结点都有两个子结点;

*完美二叉树

一个满二叉树,所有叶子都在同一个深度或同一级,并且每个父节点都有两个子节点;

*完全二叉树:

若设二叉树的深度为h,除第h层外,其它各层(1〜h-1>的结点数

都达到最大个数,第h层所有的结点都连续集中在最左边,这就是完全二叉树。

中,调度程序反复提取队列中第一个作业并运行,因而实际情况中某些时间较短的任务将

等待很长时间才能结束,或者某些不短小,但具有重要性的作业,同样应当具有优先权。

堆即为解决此类问题设计的一种数据结构。

下面列出一些基于二叉树和堆的算法:

二叉树前序遍历

二叉树中序遍历

4二叉树后序遍历

•字梯

•验证二叉查找树

«把二叉树变平放到链表里

«二叉树路径和

«从前序和后序构建二叉树

-把有序数组转换为二叉查找树

•把有序列表转为二叉查找树

•最小深度二叉树

•二叉树最大路径和

•平衡二叉树

4.Graph

与Graph相关的问题主要集中在深度优先搜索和宽度优先搜索。

深度优先搜索非常简单,你可以从根节点开始循环整个邻居节点。

下面是一个非常简单的宽度优先搜索例子,核心是用队列去存储节点。

第一步,定义一个GraphNode

classGraphNode{

intval。

GraphNodenext。

GraphNode[]neighbors。

booleanvisited。

GraphNode(intx>{

val=x。

}

GraphNode(intx,GraphNode[]n>{

}

val=x。

neighbors=n。

}

publicStringtoString(>{

return"value:

"+this.val

}

第二步,定义一个队列

classQueue{

GraphNodefirst,last。

publicvoidenqueue(GraphNoden>{if(first==null>{

first=n。

last=first。

}else{

last.next=n。

last=n。

}

}

publicGraphNodedequeue(>{

if(first=

=null>{

returnnull。

 

}else{

GraphNodetemp=newGraphNode(first.val,

first.neighbors〉。

first=first.next。

returntemp。

第三步,使用队列进行宽度优先搜索

publicclassGraphTest{

publicstaticvoidmain(String[]args>{

GraphNoden1=newGraphNode(1>。

GraphNoden2=newGraphNode(2>。

GraphNoden3=newGraphNode(3>。

GraphNoden4=newGraphNode(4>。

GraphNoden5=newGraphNode(5>。

n1.neighbors=newGraphNode[]{n2,n3,n5}

n2.neighbors=newGraphNode[]{n1,n4}。

n3.neighbors=newGraphNode[]{n1,n4,n5}。

n4.neighbors=newGraphNode[]{n2,n3,n5}。

n5.neighbors=newGraphNode[]{n1,n3,n4}。

breathFirstSearch(n1,5>。

}

publicstaticvoidbreathFirstSearch(GraphNoderoot,intx>{if(root.val==x>

System.out.println("findinroot">。

Queuequeue=newQueue(>。

root.visited=true。

queue.enqueue(root>。

while(queue.first!

=null>{

GraphNodec=(GraphNode>queue.dequeue(>。

for(GraphNoden:

c.neighbors>{

if(!

n.visited>{

System.out.print(n+"">。

n.visited=true。

if(n.val==x>

System.out.println(”Find"+n>。

queue.enqueue(n>。

}

}

}

}

}

输出结果:

value:

2value:

3value:

5Findvalue:

5

value:

4

实际中,基于Graph需要经常用到的算法:

*克隆Graph

5.排序

不同排序算法的时间复杂度,大家可以到wiki上查看它们的基本思想。

BinSort、RadixSort和CountSort使用了不同的假设,所有,它们不是一般的排序方法。

下面是这些算法的具体实例,另外,你还可以阅读:

Java开发者在实际操作中是如何排

序的。

*归并排序

*快速排序

*插入排序

6.递归和迭代

F面通过一个例子来说明什么是递归。

问题:

这里有n个台阶,每次能爬1或2节,请问有多少种爬法?

步骤1:

查找n和n-1之间的关系

为了获得n,这里有两种方法:

一个是从第一节台阶到n-1或者从2到n-2。

如果f(n>种爬

法刚好是爬到n节,那么f(n>=f(n-1>+f(n-2>。

步骤2:

确保开始条件是正确的

f(0>=0。

f(1>=1。

publicstaticintf(intn>{

if(n<=2>returnn

intx=f(n-1>+f(n-2>

returnx。

}

递归方法的时间复杂度指数为n,这里会有很多冗余计算。

f(5>

f(4>+f(3>

f(3>+f(2>+f(2>+f(1>

f(2>+f(1>+f(2>+f(2>+f(1>

该递归可以很简单地转换为迭代。

publicstaticintf(intn>{

if(n<=2>{

returnn。

}

intfirst=1,second=2。

intthird=0。

for(inti=3。

i<=n。

i++>{

third=first+second。

first=second。

second=third。

}

returnthird。

}

在这个例子中,迭代花费的时间要少些。

关于迭代和递归,你可以去这里看看。

7.动态规划

动态规划主要用来解决如下技术问题:

*通过较小的子例来解决一个实例;

*对于一个较小的实例,可能需要许多个解决方案;

-把较小实例的解决方案存储在一个表中,一旦遇上,就很容易解决;

*附加空间用来节省时间。

上面所列的爬台阶问题完全符合这四个属性,因此,可以使用动态规划来解决:

publicstaticint[]A=newint[100]

publicstaticintf3(intn>{

if(n<=2>

A[n]=n。

if(A[n]>0>

returnA[n]。

else

//storeresultssoonly

A[n]=f3(n-1>+f3(n-2>calculateonce!

returnA[n]。

}

一些基于动态规划的算法:

*编辑距离

*最长回文子串

*单词分割

*最大的子数组

8.位操作

位操作符:

从一个给定的数n中找位i

publicstaticbooleangetBit(intnum,inti>{

intresult=num&(1<

if(result:

==0>{

returnfalse。

}else{

returntrue。

}

}

 

例如,获取10的第二位:

i=1,n=10

1<<1=10

1010&10=10

10isnot0,soreturntrue

典型的位算法:

*FindSingleNumber

*MaximumBinaryGap

9.概率

通常要解决概率相关问题,都需要很好地格式化问题,下面提供一个简单的例子:

有50个人在一个房间,那么有两个人是同一天生日的可能性有多大?

<忽略闰年,即一年

有365天)

算法:

publicstaticdoublecaculateProbability(intn>{

doublex=1。

for(inti=0。

i

i++>{

x*=(365.04/365.0。

}

doublepro=Math.round((1-x>*100>returnpro/100。

}

结果:

calculateProbability(50>=0.97

10.组合和排列

组合和排列的主要差别在于顺序是否重要。

例1:

1、2、3、4、5这5个数字,输出不同的顺序,其中4不可以排在第三位,3和5不能相邻,请问有多少种组合?

例2:

有5个香蕉、4个梨、3个苹果,假设每种水果都是一样的,请问有多少种不同的组合?

基于它们的一些常见算法

排列

排列2

排列顺序

来自:

ProgramCreek

展开阅读全文
相关搜索

当前位置:首页 > 人文社科 > 法律资料

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1