算法学习【4】

1、判断一个二进制数中有多少个1

      思路1:时间复杂度为O(二进制数长度)。判断最右一位是否为1并赋值"num+=v&0x0x",数右移一位"v>>1",循环直到数为0。

      思路2:时间复杂度为O(二进制数中1个数)

                    将二进制数中最右的1置0,v = v&(v-1), num++循环直到数为0

	int count(int v){
		int num = 0;
		while(v){
			v &= (v-1);
			num++;
		}
		return num;
	}
      该思路在于(v-1)是将数中最右的1所在位变成0,然后用与运算消除后面产生的1,达到只将最右的1置0的效果。



2、函数Rand5()随机产生1、2、3、4、5中的一个数,且机率相等,基于该函数如何写出函数Rand7(),即随机产生1~7且机率相同

      由于Rand5()只是产生离散数1~5,如果只调用一次Rand5()再进行变换,每个数产生的机率仍是1/5,因此该问题的核心在于找出七种不同且出现机率相同的数

      调用N次Rand5()方法,将出现5^N种有序排序,如果直接加减乘除则产生机率不同的数,即使拼凑也难以控制机率相同,因此最好保证5^N种有序排序通过某种运算结果还是5^N种、机率必然相同。而且,5^N个数肯定无法被7整除,因此某些情况出现一定会被踢出,并再次调用Rand7()。

      以N=2为例,即调用2次Rand5(),将两次结果加起来,为了保证运算结果还是5^N种、出现机率相同,将第一次运行结果乘以10,即:x = 10*Rand5() + Rand5()

      x等机率随机出现(11、12、13、14、15、21、....、25、31、...、35、41、...、45、51、...55)之一,总共25个数。要等机率出现1~7,选择前21种情况对应,出现后面4种情况出现后重新调用Rand5()。可采用switch语句判断x = 10*Rand5() + Rand5()实现程序。更好的,我们可以考虑,为了让x连续,即选择

x = 5*(Rand5() - 1)+ Rand5()

      x等机率随机出现(1、2、3、...、25)之一,返回时就不用switch语句判断,而是返回(x-1)/3+1。

      后面剔除的4种情况出现概率为16%,每次出现后都要再进行上述操作,可以改变N算出最好的概率。

      文献http://www.cricode.com/2456.html讲的不错。



3、给定三个数,如何组合三个数使产生的新数最大,(例58、52、5可组合成58525、58552、52585、....,其中58552最大)

      思路:每两个数比较的时候,将两个数补成相同长度,补齐策略是补上数左边相同部分

     代码如下:

import java.util.*;

public class MyCode2{
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		int n1 = sc.nextInt();
		int n2 = sc.nextInt();
		int n3 = sc.nextInt();
		sc.close();
		
		if(isBigger(n1,n2)){
			if(isBigger(n1,n3))
				if(isBigger(n2,n3))
					System.out.println(n1+","+n2+","+n3);
				else
					System.out.println(n1+","+n3+","+n2);
			else
				System.out.println(n3+","+n1+","+n2);
		}
		else{
			if(isBigger(n1,n3))
				System.out.println(n2+","+n1+","+n3);
			else{
				if(isBigger(n2,n3))
					System.out.println(n2+","+n3+","+n1);
				else
					System.out.println(n3+","+n2+","+n1);
			}
		}	
	}
	
	public static boolean isBigger(int a, int b){
		boolean rst = false;
		LinkedList<Integer> A = new LinkedList<Integer>();
		LinkedList<Integer> B = new LinkedList<Integer>();
		LinkedList<Integer> temp = new LinkedList<Integer>();
		while(a>0){
			A.add(a%10);
			a = a/10;
		}
		while(b>0){
			B.add(b%10);
			b = b/10;
		}
		int len = A.size()>B.size()?A.size():B.size();
		
		for(int i=0;i<len;i++){
			//System.out.println(i+" "+A.getLast()+" "+B.getLast());
			if(A.getLast()>B.getLast()){
				rst = true;
				break;
			}else if(A.getLast()<B.getLast()){
				rst = false;
				break;
			}
			else if(A.getLast()==B.getLast()){
				temp.addFirst(A.getLast());
				A.removeLast();
				B.removeLast();
			}
			
			if(A.isEmpty()){
				A = temp;
			}
			if(B.isEmpty()){
				B = temp;
			}
		}
		return rst;
	}
}

示例:

      输入:1   2   3          输出:  3,2,  1

      输入:58 52 5          输出:58,5,  52

      输入:5250 52 6      输出:  6,52,5250


4、商标上的字符串打印后发现字符‘g’和‘9’很难分清,现需采用手段进行补救,首先需找出所有可能产生的字符串,例如“99”,可能被认为是“99”、“9g“、“g9”、“gg”。

      若字符串中字符‘g’和‘9’的总个数是n,则可能产生2^n种情况,并且可以发现其与二进制数有某种相似之处,因此直接将二进制中的‘0’、‘1’与‘g’和‘9’替换即可。代码如下:

import java.util.*;

public class CodeOne{
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		String str = sc.nextLine();
		sc.close();

		ArrayList<Integer> al = new ArrayList<Integer>();
		for(int i=0;i<str.length();i++){
			char ch = str.charAt(i);
			if(ch=='9'||ch=='g')
				al.add(i);
		}

		int N = (int)Math.pow(2, al.size());
		for(int j=0;j<N;j++){
			StringBuffer sbur = new StringBuffer(str);

			//转换成二进制字符串并补齐
			String binstr = Integer.toBinaryString(j);
			while(binstr.length()<al.size()){
				binstr = "0"+binstr;
			}
			System.out.println(binstr);

			//二进制与字符替换
			for(int k=0;k<al.size();k++){
				if(binstr.charAt(k)=='0')
					sbur.setCharAt(al.get(k), '9');
				else if(binstr.charAt(k)=='1')
					sbur.setCharAt(al.get(k), 'g');
			}
			System.out.println(sbur);
		}
	}
}

示例:

      输入:99                输出:99、9g、g9、gg

      输入:0129g          输出:01299、0129g、012g9、012gg



      前3道是2016年携程机试与面试题,第4道是2016年网易机试题。


发布了43 篇原创文章 · 获赞 50 · 访问量 14万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章