您的位置:首页 > 其它

每天一道算法题,菜鸟也能成高手!哈哈(2011年12月篇)

2011-12-02 22:07 239 查看
1、谷歌面试题:给定一个排序数组,如何构造一个二叉排序树?
by the way:

二叉排序树(Binary Sort Tree)又称二叉查找树。

它或者是一棵空树;或者是具有下列性质的二叉树:

(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;

(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;

(3)左、右子树也分别为二叉排序树;

解法:采用递归算法。

选取数组中间的一个元素作为根节点,左边的元素构造左子树,右边的节点构造有子树。

2、谷歌面试题:数组中是否有两个数的和为10

1.

比较任意两个数的和是否为10。如

for (int i = 0; i < n; ++i) { for (int j = i+1; j < n; ++j) { .... }}

复杂度为O(n*n)。

2.

将数组排序后,对每个数m,使用二分查找在数组中寻找10-m。

复杂度为O(nlogn)。

3.

将数组存储到hash_set中去,对每个数m,在hash_set中寻找10-m。

复杂度为O(n)。

4.

如果数组很大,超过内存的容量,可以按照hash(max(m, 10-m))%g,将数据分到g个小的group中。然后对每个小的group进行单独处理。

复杂度为O(n)。

方法3和4没有很好的理解,我使用了方法2。

import java.lang.reflect.Array;
import java.util.*;
public class sum2ten {
static void find_ten1(int[] a){
Arrays.sort(a);
System.out.print("排序后的序列:");
for(int k=0;k<a.length;k++){
System.out.print(a[k]+",");}
System.out.println("");
for(int i=0,j=a.length-1;i<j;)
{
if(a[i]+a[j]<10){i++;}
else if(a[i]+a[j]>10){j--;}
else{
System.out.println("a["+i+"]+"+"a["+j+"]="+10);
i++;j--;
}
}
}
public static void main(String[] agrs){
int A[]=new int[20];
int i;
System.out.print("排序前的序列:");
for(i=0;i<A.length;i++){
A[i]=(int) (10*Math.random()); System.out.print(A[i]+",");}
System.out.println("");
find_ten1(A);
}
}




3、华为面试题:找出字符串中的数字和字母,字母要求大写输出

Ps:java如何判断输入是汉字还是英文?

只要分析字符串中每个字符是中文或英文就行了
你需要一个判断字符是中文或英文的函数

因为java中字符类型char是以unicode存储的
所以不管是中文字符还是英文字符  都可以通过判断char的Unicode范围
boolean isCnorEn(char c)
{
if((c >= 0x0391 && c <= 0xFFE5)  //中文字符
|| (c>=0x0000 && c<=0x00FF))   //英文字符
return true;
return false;
}


源码:

import java.io.IOException;
import java.util.Scanner;

public class NumAndLetters {
static char LetterShiftCase(char letter){
char Sletter=(char) (letter-32);
return Sletter;
}
static void Filter(char X){
if((X>='0' && X<='9')||(X>='A' && X<='Z')){System.out.print(X);}
else if(X>='a'&&X<='z'){System.out.print(LetterShiftCase(X));}
}
public static void main(String[] args) throws IOException{
Scanner scan=new Scanner(System.in);
String s=scan.next();  //返回一个String 对象
char c= s.charAt(0) ;
int i=1;
while(c!='#'){
Filter(c);
c= s.charAt(i);
i++;
}
}
}


测试结果:



4、迅雷面试题:两整数相除,求循环节

求循环节,若整除则返回NULL,否则返回char*指向循环节。先写思路。

函数原型:char* get_circle_digits(unsigned k,unsigned j)

ps:如果无限小数的小数点后,从某一位起向右进行到某一位止的一节数字循环出现,首尾衔接,称这种小数为循环小数,这一节数字称为循环节.

分析:

回想我们使用手算时如何发现循环节:

- 如果除得的余数等于0,则说明整除;

- 如果除得的余数不等于0,则将余数乘以10,继续相除;

直到发现两次获得的余数相等,则找到了循环节。
使用java实现:

import java.awt.List;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Scanner;
public class Repetend {
static boolean ifExists(ArrayList list,int key){
if(list.contains(key)) return true;
else {
list.add(key);//将新产生的余数存到余数集合
return false;}
}
static void findRetend(int dividend ,int divisor){
ArrayList list=new ArrayList();//余数集合
ArrayList list2=new ArrayList();//商的集合
int result;
int flag=-1;//第一次计算结果不放入商的集合的标志
int iflag=-1;//循环跳出标志
while(iflag==-1){
result=dividend%divisor;
//System.out.println(result);
if(result==0){System.out.print("可以除尽");iflag=0;}//可以除尽的话就直接跳出
else{
if(flag==-1){dividend=10*result;}//第一次计算的记过都不放到商的集合里面去
else{
if(ifExists(list,result))
{System.out.print(list2);
iflag=0;}//判断新生成的余数是否出现过,出现过就直接跳出循环,并打印商集
else{//若没有出现过
list2.add(dividend/divisor);//将商放入商集
dividend=10*result;//并将余数左移一位
}
}
}
flag=0;
}
}
public static void main(String[]args)
{
Scanner scan=new Scanner(System.in);
int dividend=scan.nextInt();
int divisor=scan.nextInt();
System.out.print(dividend+"/"+divisor+"的循环节为:");
findRetend(dividend,divisor);
}
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: