Java程序员面试题集(136-150)

摘要:这一部分主要是数据结构和算法相关的面试题目,虽然只有15道题目,但是包含的信息量还是很大的,很多题目背后的解题思路和算法是非常值得玩味的。

136、给出下面的二叉树先序、中序、后序遍历的序列?


答:先序序列:ABDEGHCF;中序序列:DBGEHACF;后序序列:DGHEBFCA。

补充:二叉树也称为二分树,它是树形结构的一种,其特点是每个结点至多有二棵子树,并且二叉树的子树有左右之分,其次序不能任意颠倒。二叉树的遍历序列按照访问根节点的顺序分为先序(先访问根节点,接下来先序访问左子树,再先序访问右子树)、中序(先中序访问左子树,然后访问根节点,最后中序访问右子树)和后序(先后序访问左子树,再后序访问右子树,最后访问根节点)。如果知道一棵二叉树的先序和中序序列或者中序和后序序列,那么也可以还原出该二叉树。

例如,已知二叉树的先序序列为:xefdzmhqsk,中序序列为:fezdmxqhks,那么还原出该二叉树应该如下图所示:

137、你知道的排序算法都哪些?用Java写一个排序系统。

答:稳定的排序算法有:插入排序、选择排序、冒泡排序、鸡尾酒排序、归并排序、二叉树排序、基数排序等;不稳定排序算法包括:希尔排序、堆排序、快速排序等。

下面是关于排序算法的一个列表:

下面按照策略模式给出一个排序系统,实现了冒泡、归并和快速排序。

Sorter.java

package com.jackfrued.util;import java.util.Comparator;/*** 排序器接口(策略模式: 将算法封装到具有共同接口的独立的类中使得它们可以相互替换)* @author骆昊**/
public interface Sorter {/*** 排序* @param list 待排序的数组*/public <T extends Comparable<T>> void sort(T[] list);/*** 排序* @param list 待排序的数组* @param comp 比较两个对象的比较器*/public <T> void sort(T[] list, Comparator<T> comp);
}

BubbleSorter.java

package com.jackfrued.util;import java.util.Comparator;/*** 冒泡排序* @author骆昊**/
public class BubbleSorter implements Sorter {@Overridepublic <T extends Comparable<T>> void sort(T[] list) {boolean swapped = true;for(int i = 1; i < list.length && swapped;i++) {swapped= false;for(int j = 0; j < list.length - i; j++) {if(list[j].compareTo(list[j+ 1]) > 0 ) {T temp = list[j];list[j]= list[j + 1];list[j+ 1] = temp;swapped= true;}}}}@Overridepublic <T> void sort(T[] list,Comparator<T> comp) {boolean swapped = true;for(int i = 1; i < list.length && swapped; i++) {swapped = false;for(int j = 0; j < list.length - i; j++) {if(comp.compare(list[j], list[j + 1]) > 0 ) {T temp = list[j];list[j]= list[j + 1];list[j+ 1] = temp;swapped= true;}}}}
}

MergeSorter.java

package com.jackfrued.util;import java.util.Comparator;/*** 归并排序* 归并排序是建立在归并操作上的一种有效的排序算法。* 该算法是采用分治法(divide-and-conquer)的一个非常典型的应用,* 先将待排序的序列划分成一个一个的元素,再进行两两归并,* 在归并的过程中保持归并之后的序列仍然有序。* @author骆昊**/
public class MergeSorter implements Sorter {@Overridepublic <T extends Comparable<T>> void sort(T[] list) {T[] temp = (T[]) new Comparable[list.length];mSort(list,temp, 0, list.length- 1);}private <T extends Comparable<T>> void mSort(T[] list, T[] temp, int low, int high) {if(low == high) {return ;}else {int mid = low + ((high -low) >> 1);mSort(list,temp, low, mid);mSort(list,temp, mid + 1, high);merge(list,temp, low, mid + 1, high);}}private <T extends Comparable<T>> void merge(T[] list, T[] temp, int left, int right, int last) {int j = 0; int lowIndex = left; int mid = right - 1; int n = last - lowIndex + 1; while (left <= mid && right <= last){ if (list[left].compareTo(list[right]) < 0){ temp[j++] = list[left++]; } else { temp[j++] = list[right++]; } } while (left <= mid) { temp[j++] = list[left++]; } while (right <= last) { temp[j++] = list[right++]; } for (j = 0; j < n; j++) { list[lowIndex + j] = temp[j]; } }@Overridepublic <T> void sort(T[] list, Comparator<T> comp) {T[]temp = (T[])new Comparable[list.length];mSort(list,temp, 0, list.length- 1, comp);}private <T> void mSort(T[] list, T[] temp, int low, int high, Comparator<T> comp) {if(low == high) {return ;}else {int mid = low + ((high -low) >> 1);mSort(list,temp, low, mid, comp);mSort(list,temp, mid + 1, high, comp);merge(list,temp, low, mid + 1, high, comp);}}private <T> void merge(T[] list, T[]temp, int left, int right, int last, Comparator<T> comp) {int j = 0; int lowIndex = left; int mid = right - 1; int n = last - lowIndex + 1; while (left <= mid && right <= last){ if (comp.compare(list[left], list[right]) <0) { temp[j++] = list[left++]; } else { temp[j++] = list[right++]; } } while (left <= mid) { temp[j++] = list[left++]; } while (right <= last) { temp[j++] = list[right++]; } for (j = 0; j < n; j++) { list[lowIndex + j] = temp[j]; } }}

QuickSorter.java

package com.jackfrued.util;import java.util.Comparator;/*** 快速排序* 快速排序是使用分治法(divide-and-conquer)依选定的枢轴* 将待排序序列划分成两个子序列,其中一个子序列的元素都小于枢轴,* 另一个子序列的元素都大于或等于枢轴,然后对子序列重复上面的方法,* 直到子序列中只有一个元素为止* @author Hao**/
public class QuickSorter implements Sorter {@Overridepublic <T extends Comparable<T>> void sort(T[] list) {quickSort(list, 0, list.length- 1);}@Overridepublic <T> void sort(T[] list, Comparator<T> comp) {quickSort(list, 0, list.length- 1, comp);}private <T extends Comparable<T>> void quickSort(T[] list, int first, int last) {if (last > first) {int pivotIndex = partition(list, first, last);quickSort(list, first, pivotIndex - 1);quickSort(list, pivotIndex, last);}}private <T> void quickSort(T[] list, int first, int last,Comparator<T> comp) {if (last > first) {int pivotIndex = partition(list, first, last, comp);quickSort(list, first, pivotIndex - 1, comp);quickSort(list, pivotIndex, last, comp);}}private <T extends Comparable<T>> int partition(T[] list, int first, int last) {T pivot = list[first];int low = first + 1;int high = last;while (high > low) {while (low <= high && list[low].compareTo(pivot) <= 0) {low++;}while (low <= high && list[high].compareTo(pivot) >= 0) {high--;}if (high > low) {T temp = list[high];list[high]= list[low];list[low]= temp;}}while (high > first&& list[high].compareTo(pivot) >= 0) {high--;}if (pivot.compareTo(list[high])> 0) {list[first]= list[high];list[high]= pivot;return high;}else {return low;}}private <T> int partition(T[] list, int first, int last, Comparator<T> comp) {T pivot = list[first];int low = first + 1;int high = last;while (high > low) {while (low <= high&& comp.compare(list[low], pivot) <= 0) {low++;}while (low <= high&& comp.compare(list[high], pivot) >= 0) {high--;}if (high > low) {T temp = list[high];list[high] = list[low];list[low]= temp;}}while (high > first&& comp.compare(list[high], pivot) >= 0) {high--;}if (comp.compare(pivot,list[high]) > 0) {list[first]= list[high];list[high]= pivot;return high;}else {return low;}}}

138、写一个二分查找(折半搜索)的算法。

答:折半搜索,也称二分查找算法、二分搜索,是一种在有序数组中查找某一特定元素的搜索算法。搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。

package com.jackfrued.util;import java.util.Comparator;public class MyUtil {public static <T extends Comparable<T>> int binarySearch(T[] x, T key) {return binarySearch(x, 0, x.length- 1, key);}public static <T> int binarySearch(T[] x, T key, Comparator<T> comp) {int low = 0;int high = x.length - 1;while (low <= high) {int mid = (low + high) >>> 1;int cmp = comp.compare(x[mid], key);if (cmp < 0) {low = mid + 1;}else if (cmp > 0) {high = mid - 1;}else {return mid;}}return -1;}private static <T extends Comparable<T>> int binarySearch(T[] x, int low, int high, T key) {if(low <= high) {int mid = low + ((high -low) >> 1);if(key.compareTo(x[mid]) == 0) {return mid;}else if(key.compareTo(x[mid])< 0) {return binarySearch(x,l ow, mid - 1, key);}else {return binarySearch(x, mid + 1, high, key);}}return -1;}
}

说明:两个版本一个用递归实现,一个用循环实现。需要注意的是计算中间位置时不应该使用(high+ low) / 2的方式,因为加法运算可能导致整数越界,这里应该使用一下三种方式之一:low+ (high – low) / 2或low + (high – low) >> 1或(low + high) >>> 1(注:>>>是逻辑右移,不带符号位的右移)

139、统计一篇英文文章中单词个数。

答:

import java.io.FileReader;public class WordCounting {public static void main(String[] args) {try(FileReader fr = new FileReader("a.txt")) {int counter = 0;boolean state = false;int currentChar;while((currentChar= fr.read()) != -1) {if(currentChar== ' ' || currentChar == '\n'|| currentChar == '\t' || currentChar == '\r') {state = false;}else if(!state) {state = true;counter++;}}System.out.println(counter);}catch(Exceptione) {e.printStackTrace();}}
}

补充:这个程序可能有很多种写法,这里选择的是Dennis M. Ritchie和Brian W. Kernighan老师在他们不朽的著作《The C Programming Language》中给出的代码,向两位老师致敬。下面的代码也是如此。

140、输入年月日,计算该日期是这一年的第几天。

答:

import java.util.Scanner;public class DayCounting {public static void main(String[] args) {int[][] data = {{31,28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},{31,29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};Scanner sc = newScanner(System.in);System.out.print("请输入年月日(1980 11 28): ");int year = sc.nextInt();int month = sc.nextInt();int date = sc.nextInt();int[] daysOfMonth = data[(year % 4 == 0 && year % 100 != 0 || year % 400 == 0)?1 : 0];int sum = 0;for(int i = 0; i < month -1; i++) {sum += daysOfMonth[i];}sum += date;System.out.println(sum);sc.close();}
}

141、约瑟夫环:15个基督教徒和15个非教徒在海上遇险,必须将其中一半的人投入海中,其余的人才能幸免于难,于是30个人围成一圈,从某一个人开始从1报数,报到9的人就扔进大海,他后面的人继续从1开始报数,重复上面的规则,直到剩下15个人为止。结果由于上帝的保佑,15个基督教徒最后都幸免于难,问原来这些人是怎么排列的,哪些位置是基督教徒,哪些位置是非教徒。

答:

public class Josephu {private static final int DEAD_NUM = 9;public static void main(String[] args) {boolean[] persons = new boolean[30];for(int i = 0; i < persons.length; i++) {persons[i] = true;}int counter = 0;int claimNumber = 0;int index = 0;while(counter < 15) {if(persons[index]) {claimNumber++;if(claimNumber == DEAD_NUM) {counter++;claimNumber= 0;persons[index]= false;}}index++;if(index >= persons.length) {index= 0;}}for(boolean p : persons) {if(p) {System.out.print("基");}else {System.out.print("非");}}}
}

142、回文素数:所谓回文数就是顺着读和倒着读一样的数(例如:11,121,1991…),回文素数就是既是回文数又是素数(只能被1和自身整除的数)的数。编程找出11~9999之间的回文素数。

答:

public class PalindromicPrimeNumber {public static void main(String[] args) {for(int i = 11; i <= 9999; i++) {if(isPrime(i) && isPalindromic(i)) {System.out.println(i);}}}public static boolean isPrime(int n) {for(int i = 2; i <= Math.sqrt(n); i++) {if(n % i == 0) {return false;}}return true;}public static boolean isPalindromic(int n) {int temp = n;int sum = 0;while(temp > 0) {sum= sum * 10 + temp % 10;temp/= 10;}return sum == n;}
}

143、全排列:给出五个数字12345的所有排列。

答:

public class FullPermutation {public static void perm(int[] list) {perm(list,0);}private static void perm(int[] list, int k) {if (k == list.length) {for (int i = 0; i < list.length; i++) {System.out.print(list[i]);}System.out.println();}else{for (int i = k; i < list.length; i++) {swap(list, k, i);perm(list, k + 1);swap(list, k, i);}}}private static void swap(int[] list, int pos1, int pos2) {int temp = list[pos1];list[pos1] = list[pos2];list[pos2] = temp;}public static void main(String[] args) {int[] x = {1, 2, 3, 4, 5};perm(x);}
}

144、对于一个有N个整数元素的一维数组,找出它的子数组(数组中下标连续的元素组成的数组)之和的最大值。

答:下面给出几个例子(最大子数组用粗体表示):

1) 数组:{ 1, -2, 3,5, -3, 2 },结果是:8

2) 数组:{ 0, -2, 3, 5, -1, 2 },结果是:9

3) 数组:{ -9, -2,-3, -5, -3 },结果是:-2

可以使用动态规划的思想求解:

public class MaxSum {private static int max(int x, int y) {return x > y? x: y;}public static int maxSum(int[] array) {int n = array.length;int[] start = new int[n];int[] all = new int[n];all[n - 1] = start[n - 1] = array[n - 1];for(int i = n - 2; i >= 0;i--) {start[i] = max(array[i], array[i] + start[i + 1]);all[i] = max(start[i], all[i + 1]);}return all[0];}public static void main(String[] args) {int[] x1 = { 1, -2, 3, 5,-3, 2 };int[] x2 = { 0, -2, 3, 5,-1, 2 };int[] x3 = { -9, -2, -3,-5, -3 };System.out.println(maxSum(x1));   // 8System.out.println(maxSum(x2));   // 9System.out.println(maxSum(x3));   //-2}
}

145、用递归实现字符串倒转

答:

public class StringReverse {public static String reverse(String originStr) {if(originStr == null || originStr.length()== 1) {return originStr;}return reverse(originStr.substring(1))+ originStr.charAt(0);}public static void main(String[] args) {System.out.println(reverse("hello"));}
}

146、输入一个正整数,将其分解为素数的乘积。

答:

public class DecomposeInteger {private static List<Integer> list = newArrayList<Integer>();public static void main(String[] args) {System.out.print("请输入一个数: ");Scanner sc = newScanner(System.in);int n = sc.nextInt();decomposeNumber(n);System.out.print(n + " = ");for(int i = 0; i < list.size() - 1; i++) {System.out.print(list.get(i) + " * ");} System.out.println(list.get(list.size() - 1));}public static void decomposeNumber(int n) {if(isPrime(n)) {list.add(n);list.add(1);}else {doIt(n, (int)Math.sqrt(n));}}public static void doIt(int n, int div) {if(isPrime(div) && n % div == 0) {list.add(div);decomposeNumber(n / div);}else {doIt(n, div - 1);}}public static boolean isPrime(int n) {for(int i = 2; i <= Math.sqrt(n);i++) {if(n % i == 0) {return false;}}return true;}
}

147、一个有n级的台阶,一次可以走1级、2级或3级,问走完n级台阶有多少种走法。

答:可以通过递归求解。

public class GoSteps {public static int countWays(int n) { if(n < 0) { return 0; } else if(n == 0) { return 1; } else { return countWays(n - 1) + countWays(n - 2) + countWays(n -3); } } public static void main(String[] args) { System.out.println(countWays(5));   // 13  }
}

148、写一个算法判断一个英文单词的所有字母是否全都不同(不区分大小写)。

答:

public class AllNotTheSame {public static boolean judge(String str) {String temp = str.toLowerCase();int[] letterCounter = new int[26];for(int i = 0; i <temp.length(); i++) {int index = temp.charAt(i)- 'a';letterCounter[index]++;if(letterCounter[index] > 1) {return false;}}return true;}public static void main(String[] args) {System.out.println(judge("hello"));System.out.print(judge("smile"));}
}

149、有一个已经排好序的整数数组,其中存在重复元素,请将重复元素删除掉,例如,A= [1, 1, 2, 2, 3],处理之后的数组应当为A= [1, 2, 3]。

答:

import java.util.Arrays;public class RemoveDuplication {public static int[] removeDuplicates(int a[]) { if(a.length <= 1) { return a; } int index = 0; for(int i = 1; i < a.length; i++) { if(a[index] != a[i]) { a[++index] = a[i]; } } int[] b = new int[index + 1]; System.arraycopy(a, 0, b, 0, b.length); return b; } public static void main(String[] args) { int[] a = {1, 1, 2, 2, 3}; a = removeDuplicates(a); System.out.println(Arrays.toString(a)); }
}

150、给一个数组,其中有一个重复元素占半数以上,找出这个元素。

答:

public class FindMost {public static <T> T find(T[] x){T temp = null;for(int i = 0, nTimes = 0; i< x.length;i++) {if(nTimes == 0) {temp= x[i];nTimes= 1;}else {if(x[i].equals(temp)) {nTimes++;}else {nTimes--;}}}return temp;}public static void main(String[] args) {String[]strs = {"hello","kiss","hello","hello","maybe"};System.out.println(find(strs));}
}

Java面试题集(136-150)相关推荐

  1. Java面试题集(1-50)

    说明:最近已经重新发布了最新的<Java面试题大全>,欢迎大家点击浏览. 下面的内容是对网上原有的Java面试题集及答案进行了全面修订之后给出的负责任的题目和答案,原来的题目中有很多重复题 ...

  2. java面试题集汇总

    http://blog.csdn.net/jackfrued/article/details/44921941  Java面试题全集(上) http://blog.csdn.net/jackfrued ...

  3. Java面试题集(86-115)

    Java程序员面试题集(86-115) 摘要:下面的内容包括Struts 2和Hibernate的常见面试题,虽然Struts 2在2013年6月曝出高危漏洞后已经显得江河日下,而Spring MVC ...

  4. 引用 JAVA面试题集

    引用 狼行天下 的 JAVA面试题集 1.C++或Java中的异常处理机制的简单原理和应用. 当J***A程序违反了J***A的语义规则时,J***A虚拟机就会将发生的错误表示为一个异  常.违反语义 ...

  5. 达内java面试题集_达内经典java面试题集(一)

    达内经典java面试题集(一) 1.HashMap和Hashtable的区别. 都属于Map接口的类,实现了将惟一键映射到特定的值上. HashMap 类没有分类或者排序.它允许一个 null 键和多 ...

  6. java实习面试题_实习生java面试题集及详细答案

    实习生java面试题集及详细答案 1.Java 有那些基本数据类型,String 是不是基本数据类型,他们有何区别. Java 语言提供了八种基本类型:六种数字类型(四个整数型,两个浮点型)字节型 b ...

  7. Java面试题集-JVM(二)

    Java面试题集-JVM(二) 1.对象的内存布局? 对象在堆内存的存储布局可分为对象头.实例数据和对⻬填充. 对象头占 12B,包括对象标记和类型指针.对象标记存储对象⾃身的运⾏时数据,如哈希码.G ...

  8. Java面试题集(116-135)

    Java程序员面试题集(116-135) 摘要:这一部分讲解基于Java的Web开发相关面试题,即便在Java走向没落的当下,基于Java的Web开发因为拥有非常成熟的解决方案,仍然被广泛应用.不管你 ...

  9. Java面试题集(131-135)

    Java程序员面试题集(131-135) 摘要:这部分内容准备重新发布为Java程序员面试题集(151-180),但这篇帖子仍然保留在这里.查看新内容请点击Java程序员面试题集(151-180) 1 ...

最新文章

  1. Linux服务器部署ssl证书教程,linux服务器在wdcp面板安装ssl证书教程
  2. 旋转角度_办公娱乐新神器!这款稳固的创意支架,360°旋转随便换角度
  3. selenium + python 登录页面,输入账号、密码,元素定位问题
  4. shell实例第20讲:linux shell date的用法
  5. 【GAN优化】GAN优化专栏上线,首谈生成模型与GAN基础
  6. VS与Matlab混合编译 - mexw64 (C++版)
  7. F - Parenthesis Checking
  8. java 线程池技术_Java线程池技术以及实现
  9. plsql轻量版记录类型2
  10. web.xml filter 不包含_Elasticsearch 之 Filter 与 Query 有啥不同?
  11. 补CEGUIFont_xmlHandler.cpp
  12. 新工具︱微软Microsoft Visual Studio的R语言模块下载试用Ing...(尝鲜)
  13. heart ultrasound from american society of echocardiography
  14. 《从零开始学Swift》学习笔记(Day 53)——do-try-catch错误处理模式
  15. [转载]使用Java将Word转为Html或txt!
  16. Acrel 2000E/G配电室综合监控系统
  17. linux vim 安装失败,ubuntu安装vim失败怎么办
  18. MySql创建视图的三种方法
  19. matlab中e如何输入,MATLAB 中如何输入 对数函数_你搜我答
  20. html1——标题栏logo、网站logo

热门文章

  1. febe_如何使用FEBE备份和恢复Firefox配置文件
  2. 刚刚,体验了一把Bing chat很爽
  3. zoj 2954 Hanoi Tower(汉诺塔)
  4. 基于EtherNet/IP实现欧姆龙NX系列PLC通信
  5. 国际巨星Ricky Martin抒情MTV
  6. linux aarch64 java环境安装(图文详细版)
  7. FPGA学习思考过程记录:一
  8. 用python的turtle库画QQ表情
  9. RSA2048签名和加密+OAEP填充方式(前端)
  10. 集成电路设计专业有计算机课程吗,集成电路设计与集成系统专业介绍