zoukankan      html  css  js  c++  java
  • 面试题目——《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;
        }
    
    }
    
  • 相关阅读:
    [Codeup 25482]选美
    [Codeup 25481] swan
    暑假集训D12总结
    [技术]浅谈重载操作符
    2020年寒假第6次学*进度记录
    2020年寒假第5次学*进度记录
    2020年寒假第4次学*进度记录
    “家庭记账本”软件开发(1)
    阅读《梦断代码》随笔(1)
    2020年寒假第三次学*进度记录
  • 原文地址:https://www.cnblogs.com/tonglin0325/p/5921170.html
Copyright © 2011-2022 走看看