算法學習【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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章