每天一道算法题,菜鸟也能成高手!哈哈(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。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/15/b73f5b3b8498d890215f62614716454b.gif)
3、华为面试题:找出字符串中的数字和字母,字母要求大写输出
Ps:java如何判断输入是汉字还是英文?
源码:
测试结果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/15/6b2ea2f1076beb9847849a750461aee6.gif)
4、迅雷面试题:两整数相除,求循环节
求循环节,若整除则返回NULL,否则返回char*指向循环节。先写思路。
函数原型:char* get_circle_digits(unsigned k,unsigned j)
ps:如果无限小数的小数点后,从某一位起向右进行到某一位止的一节数字循环出现,首尾衔接,称这种小数为循环小数,这一节数字称为循环节.
分析:
回想我们使用手算时如何发现循环节:
- 如果除得的余数等于0,则说明整除;
- 如果除得的余数不等于0,则将余数乘以10,继续相除;
直到发现两次获得的余数相等,则找到了循环节。
使用java实现:
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); } }
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/15/b73f5b3b8498d890215f62614716454b.gif)
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++; } } }
测试结果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/15/6b2ea2f1076beb9847849a750461aee6.gif)
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); } }
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/15/84e38c375019de172addfea572366b70.gif)
相关文章推荐
- 每天一道算法题,菜鸟也能成高手!哈哈(2011年11月篇)
- 每天一道算法题,菜鸟也能成高手!哈哈(2011年10月篇)
- 每天一道算法题(27)——找出元音字母并排序
- 每天一道算法题(2)——求整数的2进制表示中1的个数
- 每天一道算法题(3)——含有指针元素的模板类
- 每天一道算法题——二叉树的镜像
- 每天一道算法题(39)——含有重复字符的全排列
- 每天一道算法题3 求子数组的最大和
- 每天一道算法题18 跳台阶问题
- 每天一道算法题目——最大公约数
- 每天一道算法题(12)——和为n的连续正数序列或者随机数
- 每天一道算法题(14)——N个降序数组,找到最大的K个数
- 【每天一道算法题】循环移动
- 每天一道算法题(37)——360校招机试之寻找同乡
- java将一个正整数分解质因数(每天一道算法题)
- 每天一道算法题(30)——高效的求斐波拉契数列
- 每天一道算法题(2)——求整数的2进制表示中1的个数
- 每天一道算法_9_由后序遍历和中序遍历求前序遍历
- 每天一道算法题(31)——正数减法
- 每天一道算法题4 查找最小的k个元素