声明:所有题目都是自己曾经做过,也只作了部分测试,一定存在错漏之处,如能帮忙指出,感激不尽。其他题目等整理之后再更新
1.求一个数字的二进制表示有多少个1
public class CountOfOne { public static void main(String[] args) { //求一个数字的二进制表示有多少个1 int number=-1; print(number); System.out.println(NumberOf1(number)); } public static int NumberOf1(int n){ int count=0; while(n!=0){ count++; n=(n-1)&n; print(n); } return count; } public static void print(int n){ String binary=Integer.toBinaryString(n); int count=32-binary.length(); for(int i=0;i<count;i++){ System.out.print("0"); } System.out.println(binary+" "+n); } }
2.最短路径
题目路径:http://acm.hdu.edu.cn/vcontest/vtl/problem/showproblem/vtlid/4642/problemid/1011
public class Shortest { //http://acm.hdu.edu.cn/vcontest/vtl/problem/showproblem/vtlid/4642/problemid/1011 private int[][] table=new int[10][10]; private boolean[][] map=new boolean[10][10]; private void initTable(){ int i=5; int j=4; int number=2; table[i][j]=1; int a=1,b=2; while(number<73){ for(int d=0;d<a;d++){ table[i][++j]=number++; } for(int d=0;d<a;d++){ table[--i][j]=number++; } a+=2; for(int d=0;d<b;d++){ table[i][--j]=number++; } for(int d=0;d<b;d++){ table[++i][j]=number++; } b+=2; } for(int d=0;d<a;d++){ table[i][++j]=number++; } for(int d=0;d<a;d++){ table[--i][j]=number++; } for(int d=0;d<b-1;d++){ table[i][--j]=number++; } } private void initMap(){ map[0][3]=true; map[1][4]=map[1][6]=true; map[2][1]=map[2][7]=map[2][9]=true; map[3][0]=map[3][2]=map[3][6]=true; map[4][3]=map[4][5]=map[4][7]=true; map[5][2]=map[5][5]=map[5][6]=map[5][8]=true; map[6][1]=map[6][3]=true; map[7][0]=map[7][4]=true; map[8][1]=map[8][5]=map[8][9]=true; map[9][0]=map[9][6]=true; } private int aim; public Shortest(int a,int b){ initTable(); initMap(); aim=b; for(int i=0;i<10;i++) for(int j=0;j<10;j++){ if(table[i][j]==a){ process(i,j,0); break; } } if(bestPath==1000000){ System.out.println("impossible"); }else{ System.out.println(bestPath); } } //表示很远 private int bestPath=1000000; private void process(int i,int j,int path){ if(table[i][j]==aim){ if(path<bestPath){ bestPath=path; } } map[i][j]=true; //没有数据 有数据的为true, if(i-1>=0&&!map[i-1][j]){ //向上 process(i-1,j,path+1); } if(i+1<=9&&!map[i+1][j]){ //向下 process(i+1,j,path+1); } if(j-1>=0&&!map[i][j-1]){ //向左 process(i,j-1,path+1); } if(j+1<=9&&!map[i][j+1]){ //向右 process(i,j+1,path+1); } map[i][j]=false; } public static void main(String[] args) { int start=9; int end=32; new Shortest(start,end); } }
3.青蛙跳跃
游戏地址:http://www.macroblue.net/bbs/ShowPost.asp?ThreadID=5932
六个位置从左到右依次编号为:1,2,3,4,5,6
import java.util.ArrayList; import java.util.List; public class FrogJump { private int[] pos=new int[]{1,1,1,0,2,2,2}; private int count=0; private List<String> content=new ArrayList<String>(); public void jump(){ if(isComplete()){ for(String str:content){ System.out.println(str); } System.out.println("总共移动的次数为:"+count+"次"); System.out.println("======================="); } for(int i=0;i<7;i++){ int type=canJump(i); if(type!=-1){ content.add(print(i,type)); swap(type,i); count++; jump(); swap(type,i); count--; content.remove(count); } } } private String print(int start,int end){ //int type=pos[start]; return (start+1)+"位置的青蛙跳到空地"+(end+1); } private boolean isComplete(){ boolean result=true; for(int i=0;i<3;i++){ if(pos[i]!=2)return false; } for(int i=4;i<7;i++){ if(pos[i]!=1)return false; } return result; } private void swap(int i,int j){ int temp=pos[i]; pos[i]=pos[j]; pos[j]=temp; } private int canJump(int index){ if(pos[index]==0)return -1; //左边的青蛙 if(pos[index]==1){ if(index==6)return -1; if(pos[index+1]==0){ return index+1; }else if((index<=4&&pos[index+2]==0)){ return index+2; } }else{//右边的青蛙 if(index==0)return -1; if(pos[index-1]==0){ return index-1; }else if((index>=2&&pos[index-2]==0)){ return index-2; } } return -1; } public static void main(String[] args) { new FrogJump().jump(); } }
输出:
3位置的青蛙跳到空地4 5位置的青蛙跳到空地3 6位置的青蛙跳到空地5 4位置的青蛙跳到空地6 2位置的青蛙跳到空地4 1位置的青蛙跳到空地2 3位置的青蛙跳到空地1 5位置的青蛙跳到空地3 7位置的青蛙跳到空地5 6位置的青蛙跳到空地7 4位置的青蛙跳到空地6 2位置的青蛙跳到空地4 3位置的青蛙跳到空地2 5位置的青蛙跳到空地3 4位置的青蛙跳到空地5 总共移动的次数为:15次 ======================= 5位置的青蛙跳到空地4 3位置的青蛙跳到空地5 2位置的青蛙跳到空地3 4位置的青蛙跳到空地2 6位置的青蛙跳到空地4 7位置的青蛙跳到空地6 5位置的青蛙跳到空地7 3位置的青蛙跳到空地5 1位置的青蛙跳到空地3 2位置的青蛙跳到空地1 4位置的青蛙跳到空地2 6位置的青蛙跳到空地4 5位置的青蛙跳到空地6 3位置的青蛙跳到空地5 4位置的青蛙跳到空地3 总共移动的次数为:15次 =======================
4.将小写的数字转换成中文大写数字,如:456789 对应中文大写的:肆拾伍万陆仟柒佰捌拾玖元整
public class MoneyReverse { public static void main(String[] args) { String str=new MoneyReverse().process("456789"); System.out.println(str); } private char[] map=new char[]{'壹','貳','弎','肆','伍','陆','柒','捌','玖'}; private String[] typeMap=new String[]{"","拾","佰","仟","万","亿"}; private String [] lastMap=new String[]{"元整","万","亿","万亿"}; public String process(String str){ //去掉前面的零 str=str.replaceFirst("^0*", ""); int i=str.length(); int count=i%4==0?i/4:i/4+1; String[] part=new String[count]; int t=0; for(;t<count-1;t++){ part[t]=str.substring(i-4*(t+1),i-4*t); } part[count-1]=str.substring(0,i-4*t); t=count-1; StringBuilder builder=new StringBuilder(); for(;t>=0;t--){ builder.append(processPart(part[t], t)); } return builder.toString(); } private String processPart(String number,int type){ int count=number.length(); String result=""; for(int i=count-1;i>=0;i--){ char c=number.charAt(i); if((i!=count-1&&c=='0'&&number.charAt(i+1)!='0')||(i==0&&c=='0')){ result="零"+result; } else if(c!='0'){ result=map[c-49]+typeMap[count-1-i]+result; } } return result+lastMap[type]; } }
5.将1~9九个数字,组合成三个三位数A,B,C使其满足:B/A=2 C/A=3 有多少种这种组合?
public class NumberMerger { //false表示还没有使用 private boolean[] map=new boolean[9]; public void process(){ int firstNumber=0; //第一个数 for(int i=1;i<=3;i++){ //已用 map[i-1]=true; firstNumber+=i*100; //第二个数 for(int j=1;j<=9;j++){ if(!map[j-1]){ map[j-1]=true; firstNumber+=j*10; for(int k=1;k<=9;k++){ if(!map[k-1]){ map[k-1]=true; firstNumber+=k; validate(firstNumber); firstNumber-=k; map[k-1]=false; } } firstNumber-=j*10; map[j-1]=false; } } firstNumber-=i*100; map[i-1]=false; } } public void validate(int number){ int secondNumber=number*2; int thridNumber=number*3; if(secondNumber>=1000||thridNumber>=1000)return; String text=""+secondNumber+thridNumber; if(text.contains("0"))return; int m=100; String mapProcess=""; for(int i=0;i<3;i++){ //已经使用过 if(map[secondNumber/m-1]||map[thridNumber/m-1]){ if(!"".equals(mapProcess)){ for(int t=0;t<mapProcess.length();t++){ map[mapProcess.charAt(t)-49]=false; } } return; }else{ map[secondNumber/m-1]=true; map[thridNumber/m-1]=true; mapProcess=mapProcess+(secondNumber/m); mapProcess=mapProcess+(thridNumber/m); secondNumber=secondNumber%m; thridNumber=thridNumber%m; m/=10; } } for(int t=0;t<mapProcess.length();t++){ map[mapProcess.charAt(t)-49]=false; } System.out.println(number+","+2*number+","+3*number); } public static void main(String[] args) { new NumberMerger().process(); } }
6.求一个数字序列中最长连续递增子序列有多少个?
如这样一组序列:17 2 5 77 99 93 11 97 65 35
其最长连续递增子序列是从第二个数字2到数字99,一共4个。
import java.util.Random; public class SlopeUp { public static void main(String[] args) { int count=10; int[] nums=new int[count]; Random random=new Random(); for(int i=0;i<count;i++){ nums[i]=random.nextInt(100); System.out.print(nums[i]+" "); } System.out.println(); new SlopeUp().process(nums); } private int[] a; //a[i]表示从开始到i最长连续递增子序列个数,最后的结果为:a[a.length-1] private int[] b; //b[i]表示到当前i位置有多少个连续递增个数,如-1,2,4,0,3 则b[2]=3;b[4]=2 public void process(int[] nums){ a=new int[nums.length]; b=new int[nums.length]; for(int i=1;i<nums.length;i++){ if(nums[i]>nums[i-1]){ b[i]=b[i-1]+1; if(b[i]+1>a[i-1]){ System.out.println("The End Number Is:"+nums[i]); a[i]=b[i]+1; }else{ a[i]=a[i-1]; } }else{ a[i]=a[i-1]; } } System.out.println(a[a.length-1]); } }
7.假设这有一个各种字母组成的字符串,假设这还有另外一个字符串,而且这个字符串里的字母数相对少一些。从算法是讲,什么方法能最快的查出所有小字符串里的字母在大字符串里都有?
比如,如果是下面两个字符串:
String 1: ABCDEFGHLMNOPQRS
String 2: DCGSRQPOM
答案是true,所有在string2里的字母string1也都有。
解法1:
public class StringProcess01 { public static void main(String[] args) { String s1="ABCDEFGHLMNOPQRS"; String s2="DCGSRQPOM"; new StringProcess01().process(s1,s2); } public void process(String lengthStr,String ShortStr){ boolean hash[]=new boolean[26]; char[] scs=ShortStr.toCharArray(); int count=0;//短字符串中不同字符的个数 for(int i=0;i<scs.length;i++){ int index=scs[i]-'A'; if(!hash[index]){//为了保障count的准确 hash[index]=true; count++; } } char[] lcs=lengthStr.toCharArray(); for(int i=0;i<lcs.length;i++){ int index=lcs[i]-'A'; if(hash[index]){ hash[index]=false; count--; if(count==0)break; } } if(count==0){ System.out.println("True"); }else{ System.out.println("False"); } } }
解法2
import java.math.BigInteger; /* 假设我们有一个一定个数的字母组成字串,我给每个字母分配一个素数, 从2开始,往后类推。这样A将会是2,B将会是3,C将会是5,等等。 现在我遍历第一个字串,把每个字母代表的素数相乘。你最终会得到一个很大的整数, 对吧?然后——轮询第二个字符串,用每个字母除它。 如果除的结果有余数,这说明有不匹配的字母。 如果整个过程中没有余数,你应该知道它是第一个字串恰好的子集了。 */ public class StringProcess01_02 { public static void main(String[] args) { String str1="ABCDEFGHIJKLMNOPQRSTUVWXYZ"; String str2="SDFF"; new StringProcess01_02().process(str1, str2); } public void process(String lengthStr,String shortStr){ int[] primeNumber=new int[]{2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59,61, 67, 71, 73, 79, 83, 89, 97, 101}; BigInteger mulValuse=BigInteger.valueOf(1); char[] lca=lengthStr.toCharArray(); for(int i=0;i<lca.length;i++){ int index=lca[i]-'A'; //表示之前没有出现过该字符,可以防止相同的素数一直相乘 String re=mulValuse.remainder(BigInteger.valueOf(primeNumber[index])).toString(); if(!"0".equals(re)){ mulValuse=mulValuse.multiply(BigInteger.valueOf(primeNumber[index])); //System.out.println(mulValuse.toString()); } } char[] sca=shortStr.toCharArray(); boolean temp=true; for(int i=0;i<sca.length;i++){ int index=sca[i]-'A'; String re=mulValuse.remainder(BigInteger.valueOf(primeNumber[index])).toString(); if(!"0".equals(re)){ //只要第一个出现的不合法的字符则马上结束 //当数据多时,效率将会非常显著的提高 temp=false; break; } } if(temp){ System.out.println("True"); }else{ System.out.println("False"); } } }
8.三色旗算法(注意看清题意,否则可能不能理解代码)
题意可以查看:http://hi.baidu.com/de1zhanjie/item/bdac2bbab11d12afeaba9355
//关键:两头向中间找,找过的可以进行交换,还没有找过的不能处理 public class ThreeColorFlag02 { private int blue; //blue指针左边的值一定为蓝色 private int white; //white一直向右移动,但为白色,则直接移动,当为红色,和红色指针交换,当为蓝色指针,和蓝色指针交换 private int red; //red指针右边的值一定为红色 private char[] source; public ThreeColorFlag02(char[] s){ this.source=s; blue=0; white=0; red=source.length-1; process(); } public void process(){ //blue指针指向的为:非蓝色旗 while(source[blue]=='蓝'){ blue++; white++; } //red指针指向的为:非红色旗 while(source[red]=='红'){ red--; } //当白色指针超过红色指针,则表示结束 while(white<=red){ if(source[white]=='红'){ swap(white,red); //必须减1,否则刚刚交换完,该位置必定为红 red--; while(source[red]=='红'){ red--; } } //如果刚刚和red交换过,则可能为蓝色,或者白色 //否则,为白色 while(source[white]=='白'){ white++; } //此时white可能指向蓝色或者红色 if(source[white]=='蓝'){ swap(white,blue);//蓝色指针为遍历过的指针,所以可以交换 white++; blue++; } } } private void swap(int i,int j){ char temp=source[i]; source[i]=source[j]; source[j]=temp; } public static void main(String[] args) { char[] source=new char[]{'红','白','蓝','白','白','蓝','红','蓝','白','红'}; new ThreeColorFlag02(source); System.out.println(Arrays.toString(source)); } }
9.桶排序(看代码前要先理解桶排序的原理)
public class BucketSort { /** * * @param data 要进行排序的数据 * @param min 数据中最小的数据 * @param max 数据中最大的数据 */ public void bucketSort(int[] data,int min,int max){ int arrayLength=data.length; //临时数组,data数组的拷贝 int[] tmp=new int[arrayLength]; System.arraycopy(data, 0, tmp, 0, arrayLength); //桶数组 int[] buckets=new int[max-min]; for(int i=0;i<arrayLength;i++){ //记录每个数出现的次数 buckets[data[i]-min]++; } //对桶进行处理 for(int i=1;i<max-min;i++){ buckets[i]=buckets[i]+buckets[i-1]; } //根据桶的信息来确定数据的位置 //tmp.Data和该值对应的具体位置的映射关系为: //tmp.Data-映射->buckets.Index-得到->buckets.Data //buckets.Data-映射->data.Index-确定->data.Data //为了保证算法的稳定性,从最大索引开始 for(int i=arrayLength-1;i>=0;i--){ data[--buckets[tmp[i]-min]]=tmp[i]; } } public static void main(String[] args) { int[] data=new int[]{9,5,-1,8,5,7,3,-3,1,3}; //因为在bucketSort方法中算桶个数是max-min,所以这里的max应该要比实际的大1 new BucketSort().bucketSort(data, -3, 10); for(int num:data){ System.out.print(num+" "); } } }
10.建立最大堆
public class MaxHeap { public static void main(String[] args) { int[] source=new int[]{3,24,-1,10,5}; new MaxHeap().createHeap(source); System.out.println(Arrays.toString(source)); } private int[] source; private int length; public void createHeap(int[] s){ this.source=s; length=this.source.length-1; for(int i=length/2;i>=0;i--){ process(i); } } private void process(int index){ int left=getLeftIndex(index); int right=getRightIndex(index); int maxIndex=index; //右子树为有效子树 if(right<=length&&source[index]<source[right]){ maxIndex=right; } if(left<=length&&source[maxIndex]<source[left]){ maxIndex=left; } //最大值不是本身 if(maxIndex!=index){ swap(maxIndex,index); //这一步很重要,要递归处理交换后的新节点,保证所有的结点都符合最大堆的特点 process(maxIndex); } } //交换 private void swap(int i,int j){ int temp=source[i]; source[i]=source[j]; source[j]=temp; } private int getLeftIndex(int index){ //下标从0开始 return 2*index+1; } private int getRightIndex(int index){ return 2*index+2; } }
11.打印中文字符序列的每个字符的拼音的第一个字母:如输入:"直来直往",则输出:“ZLZW”
import java.io.UnsupportedEncodingException; public class js_02 { public static void main(String[] args) { new js_02().new answer("我深爱我的家人"); } private class answer{ private int[][] res=new int[23][2]; private String[] word={"啊","芭","擦","搭","蛾","发","噶","哈","击","喀","垃","妈","拿","哦","啪","期","然","撒","塌","挖","昔","压","匝"}; private char[] cs={'A','B','C','D','E','F','G','H','J','K','L','M','N','O','P','Q','R','S','T','W','X','Y'}; public answer(String str){ iniRes(); process(str); } private void iniRes(){ for(int i=0;i<word.length;i++){ try { byte[] bs=word[i].getBytes("GB2312"); res[i][0]=bs[0]&0xff; res[i][1]=bs[1]&0xff; } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } } for(int i=0;i<res.length;i++){ for(int j=0;j<2;j++){ System.out.print(res[i][j]+","); } System.out.println(); } } public void process(String str){ for(int i=0;i<str.length();i++){ String word=str.substring(i, i+1); try { byte[] b=word.getBytes("GB2312"); int first=b[0]&0xff; int second=b[1]&0xff; boolean isZ=true; for(int t=0;t<res.length-1;t++){ if(first>=res[t][0]&&first<res[t+1][0]){ System.out.print(cs[t]); isZ=false; break; }else if(first>=res[t][0]&&first==res[t+1][0]){//first==res[t][0]&&first==res[t+1][0] if(second<res[t+1][1]){ System.out.print(cs[t]); isZ=false; break; } } } if(isZ){ System.out.print('Z'); } } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }