面试题目——《CC150》排序与查找
面试题11.1:给定两个排序后的数组A和B,其中A的末端有足够的缓冲空间容纳B。编写一个方法,将B合并入A并排序。
package cc150.sort_search; public class MergeTwoSortedArr { public static void main(String[] args) { // TODO 自动生成的方法存根 int[] a = {1,3,5,7,9,11,13,15,0,0,0,0,0,0,0,0}; int[] b = {0,2,4,6,8,10,12,14}; MergeTwoSortedArr mt = new MergeTwoSortedArr(); mt.merge(a,b,8,8); for(int i=0;i<a.length;i++) System.out.println(a[i]); } public void merge(int[] a,int[] b,int lastA,int lastB){ int indexA = lastA-1; int indexB = lastB-1; int indexMerge = lastA+lastB-1; //递减循环 while(indexA >= 0 && indexB >= 0){ if(a[indexA] > b[indexB]) { //如果数组A的元素大于数组B的元素,先放入A a[indexMerge] = a[indexA]; indexA--; indexMerge--; }else{ a[indexMerge] = b[indexB]; indexB--; indexMerge--; } } //如果B还有元素没有放进去的话,继续放,A不用,因为仍然在原来的位置 while(indexB >= 0){ a[indexMerge] = b[indexB]; indexB--; indexMerge--; } } }
面试题11.2:编写一个方法,对字符串数组进行排序,将所有变位词排在相邻的位置。
package cc150.sort_search; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.Hashtable; import java.util.Iterator; public class AnagramSort { //牛客网题目中要求变位词的字典排序最小的数的集合,且这个集合也要是字典排序的 public static void main(String[] args) { // TODO 自动生成的方法存根 AnagramSort as = new AnagramSort(); String[] arr = {"ab","ba","abc","cba"}; Iterator ire = as.sortStrings(arr).iterator(); while(ire.hasNext()) System.out.println(ire.next()); } public String sortChars(String str) { //把字符串排序后返回 char[] content = str.toCharArray(); Arrays.sort(content); return new String(content); } public ArrayList<String> sortStrings(String[] array){ Hashtable<String,ArrayList<String>> hash = new Hashtable<String,ArrayList<String>>(); ArrayList<String> anagrams = new ArrayList<String>(); //存放每个变位词集合 ArrayList<String> result = new ArrayList<String>(); //存放每个变位词集合排序后的第一个 //将同为变位词的单词分到同一组 for(String s:array){ String key = sortChars(s); if(!hash.containsKey(key)){ hash.put(key, new ArrayList<String>()); //如果不包含变位词,建立key对应的链表 } anagrams = hash.get(key); //取得链表,并往其中加入变位词 anagrams.add(s); //加入变位词 } //将散列表排序后转换成ArrayList for(String key:hash.keySet()){ //取得key的集合,并遍历 ArrayList<String> list = hash.get(key); //一个一个取得ArrayList Collections.sort(list,new Comparator<String>(){ @Override public int compare(String str1, String str2) { // TODO Auto-generated method stub return str1.compareTo(str2); } }); result.add( list.get(0)); //取得排序后的每个变位词集合的第一个元素,加入新的链表中 Collections.sort(result,new Comparator<String>(){ //把新的链表排序后返回 @Override public int compare(String str1, String str2) { // TODO Auto-generated method stub return str1.compareTo(str2); } }); } return result; } }
面试题11.3:给定一个排序后的数组,包含n个整数,但这个数组已被旋转过很多次,次数不详。请编写代码找出数组中的某个元素。可以假定数组元素原先是按从小到大的顺序排列的。
旋转的意思是:Array1:{10,15,20,0,5}中有一半是升序排序的
package cc150.sort_search; public class Search { //注意可能有重复的元素 public static void main(String[] args) { // TODO 自动生成的方法存根 int[] a = {2,2,2,3,4,2}; Search s = new Search(); System.out.println(s.search(a,0,a.length-1,3)); } public int search(int a[],int left,int right,int x){ //查找x int mid = (left+right)/2; if(x == a[mid]) //找到元素 return mid; if(right < left) //没找到元素 return -1; //二分查找 if(a[left] < a[mid]){ //左半边正常排序 if(a[left] <= x && a[mid] >= x) //x在左半边的范围内 return search(a,left,mid-1,x); else //x不在左半边的范围内 return search(a,mid+1,right,x); }else if(a[left] > a[mid]){ //右半边正常排序 if(a[mid] <= x && a[right] >= x) //x在右半边的范围内 return search(a,mid+1,right,x); else //x不在右半边的范围内 return search(a,left,mid-1,x); }else if(a[left] == a[mid]){ //左半边都是重复元素,{2,2,2,3,4,2}的情况 if(a[mid] != a[right]) //如果右边不等于中间,只需要搜索左半边 return search(a,left,mid-1,x); else{ //否则两边都要搜索 int result = search(a,left,mid-1,x); //先搜索左半边 if(result == -1) //如果没有搜索到 return search(a,mid+1,right,x); //再搜索右半边 else return result; } } return -1; } }
面试题11.4:设想你有一个20GB的文件,每一行一个字符串。请说明将如何对这个文件进行排序。
在不能全部载入内存的情况下,使用外部排序,看《数据结构与算法分析》
面试题11.5:有一个排序后的字符串数组,其中散步着一些空字符串,编写一个方法,找出给定字符串的位置。
package cc150.sort_search; public class Finder { public static void main(String[] args) { // TODO 自动生成的方法存根 Finder fd = new Finder(); String[] arr = {"a","b","","c","","d"}; System.out.println(fd.findString(arr, 6, "c")); } //因为是有序数组,所以使用二分查找,但是有空字符串,所有当mid遇到空字符串的时候要转到最近的非空字符串 public int findString(String[] str, int n, String x) { // write code here if(str == null || str == null || str.length <= 0) return -1; return searchR(str,x,0,n-1); } public int searchR(String[] strings,String str,int first,int last){ if(first > last) return -1; int mid = (first+last)/2; //如果mid是空的情况 if(strings[mid].isEmpty()){ int left = mid-1; int right = mid+1; while(true){ //循环 if(left < first &&right > last) //返回错误 return -1; else if(right <= last && !strings[right].isEmpty()){ //如果mid的右边不超过last,且不为空的话,赋值为mid,跳出 mid = right; break; }else if(left >= first && !strings[left].isEmpty()){ //如果mid的左边不超过last,且不为空的话,赋值为mid,跳出 mid = left; break; } right++; left--; } } //对不为空的mid进行检查 if(str.equals(strings[mid])) return mid; else if(strings[mid].compareTo(str)<0) //mid小于str,对右半边继续二分查找 return searchR(strings,str,mid+1,last); else return searchR(strings,str,first,mid-1); } }
面试题11.6:给定M×N矩阵,每一行、每一列都按升序排列,请编写代码找出某元素。
package cc150.sort_search; public class FindElement { public static void main(String[] args) { // TODO 自动生成的方法存根 } public int[] findElement(int[][] mat, int n, int m, int x) { // write code here int row = 0; int column = m-1; while(row < n && column >= 0){ //从右上角开始寻找 if(mat[row][column] == x){ int[] result = {row,column}; return result; }else if(mat[row][column] > x) column--; else row++; } return null; } }
面试题11.7:有一个马戏团正在设计叠罗汉的表演节目,一个人要站在另一个人的肩膀上。出于实际和美观的考虑,在上面的人要比下面的人矮一点、轻一点。已知马戏团每个人的高度和重量,请编写代码计算叠罗汉最多能叠到几个人。(最长递增子序列)
package cc150.sort_search; public class Dieluohan { public static void main(String[] args) { // TODO 自动生成的方法存根 } public int getHeight(int[] men, int n) { //建立一个数组记录每一位的时候最长序列的长度 // write code here int[] dp = new int[n]; //存放到达每一位的时候的最长序列的长度 int max = 0; for(int i=0;i<n;i++){ dp[i] = 1; //先把每一个置为1,因为至少是1 for(int j=0;j<i;j++){ //加上了第i个后,循环前i-1个,如果有值小于等于第i个值的话,加上1,注意加上i后最长的 if(men[j] <= men[i]) dp[i] = Math.max(dp[i], dp[j]+1); } max = Math.max(dp[i], max); } return max; } }
本文只发表于博客园和tonglin0325的博客,作者:tonglin0325,转载请注明原文链接:https://www.cnblogs.com/tonglin0325/p/5921170.html