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

来源:互联网 发布:淘宝不能重新激活店铺 编辑:程序博客网 时间:2024/04/27 13:55
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);}}


 

 

 

 

 

 

 

 

 

原创粉丝点击