各大it企业编程笔试题,答案自己做的,大家批评指正(更新中)

一、8月15日,百度2道面试题:
1、来自《编程之美》的概率题:一个桶里面有白球、黑球各100个,现在按下述规则取球:的
    i 、每次从通里面拿出来两个球;
    ii、如果取出的是两个同色的求,就再放入一个黑球;
    ii、如果取出的是两个异色的求,就再放入一个白球。
问:最后桶里面只剩下一个黑球的概率是多少?

package A1;
import java.util.Random;
public class A1 {
	public int getBall(int blackBall, int whiteBall) {
		if (blackBall == 1 && whiteBall == 0) {
			return 1;
		}
		if (blackBall == 0 && whiteBall == 1) {
			return 0;
		}
		int black = 0;
		int white = 0;
		Random ram = new Random();
		int ballNum = blackBall + whiteBall;
		int ball1 = (int) ram.nextDouble() * ballNum + 1;
		int ball2 = (int) ram.nextDouble() * ballNum + 1;
		if (ball1 < blackBall) {
			black++;
		} else {
			white++;
		}
		if (ball2 < blackBall) {
			black++;
		} else {
			white++;
		}

		if (black == 2 || white == 2) {
			return getBall(blackBall - black + 1, whiteBall - white);
		} else {
			return getBall(blackBall - black, whiteBall - white + 1);
		}
	}
	public static void main(String[] args) {
		int white = 0;
		int black = 0;
		int iterator = 1000;
		A1 A = new A1();
		for (int i = 0; i < iterator; ++i) {
			if (A.getBall(100, 100) == 1) {
				black++;
			}
			if (A.getBall(100, 100) == 0) {
				white++;
			}
		}
		System.out.println(black);
		System.out.println((float)black / (float)iterator);
	}
}
发现黑球概率是百分之百,具体原因,大家想想吧。

2、算法题:给你一个自然数N,求[6,N]之内的所有素数中,两两之和为偶数的那些偶数。

package A1;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

public class A2 {
	public boolean isPrime(int n){
		if(n<2){
			return false;
		}
		for(int i=2;i<Math.sqrt(n);++i){
			if(n%i==0){
				return false;
			}
		}
		return true;
	}
	public Set<Integer> find(int n){
		if(n<6){
			return null;
		}
		Set<Integer> even=new HashSet<Integer>();
		List<Integer> prime=new ArrayList<Integer>();
		for(int i=7;i<n;i+=2){
			if(isPrime(i)){
				prime.add(i);
			}
		}
		for(int i=0;i<prime.size()-1;++i){
			for(int j=i+1;j<prime.size();++j){
				int sum=(prime.get(i)+prime.get(j));
				if(sum%2==0){
					even.add(sum);
				}
			}
		}
		return even;
	}
	public static void main(String[] args){
		A2 A=new A2();
		Set<Integer> set=A.find(100);
		Iterator<Integer> it=set.iterator();
		while(it.hasNext()){
			System.out.println(it.next());
		}
	}
}

二、9月5日,华为2014校园招聘的机试题目

通过键盘输入一串小写字母(a~z)组成的字符串。请编写一个字符串压缩程序,将字符串中连续出席的重复字母进行压缩,并输出压缩后的字符串。
压缩规则:
    1、仅压缩连续重复出现的字符。比如字符串"abcbc"由于无连续重复字符,压缩后的字符串还是"abcbc"。
    2、压缩字段的格式为"字符重复的次数+字符"。例如:字符串"xxxyyyyyyz"压缩后就成为"3x6yz"。
要求实现函数: 
     void stringZip(const char *pInputStr, long lInputLen, char *pOutputStr);
    输入pInputStr:  输入字符串lInputLen:  输入字符串长度
    输出 pOutputStr: 输出字符串,空间已经开辟好,与输入字符串等长;
注意:只需要完成该函数功能算法,中间不需要有任何IO的输入输出
示例 
    输入:“cccddecc”   输出:“3c2de2c”
    输入:“adef”     输出:“adef”
    输入:“pppppppp” 输出:“8p”

package A2;

public class A1 {
	public String compression(String str){
		if(str==null){
			return "";
		}
		StringBuffer newStr=new StringBuffer();
		int num=1;
		char pre = str.charAt(0);
		char current;
		for(int i=1;i<str.length();++i){
			current=str.charAt(i);
			if(current==pre){
				num++;
			}
			if(current!=pre){
				if(num>1){
					newStr.append(num);
				}
				newStr.append(pre);
				num=1;
			}
			pre=current;
		}
		if(num>1){
			newStr.append(num);
		}
		newStr.append(pre);
		return newStr.toString();
	}
	public static void main(String args[]){
		A1 A=new A1();
		System.out.println(A.compression("ASGGGDSGSS"));
	}
}
三、9月9日,迅雷2014校招笔试编程题:
已知集合A和B的元素分别用不含头结点的单链表存储,函数difference()用于求解集合A与B的差集,并将结果保存在集合A的单链表中。例如,若集合A={5,10,20,15,25,30},集合B={5,15,35,25},完成计算后A={10,20,30}。
链表结点的结构类型定义如下:
class Node{
  int data;
  Node next;
}

package A3;

import java.util.HashSet;
import java.util.Set;

class Node{
  int data;
  Node next;
}
public class A1 {
  public Node difference(Node a,Node b){
    Node pre=new Node();
    Node head=pre;
    pre.next=a;
    Node curr=a;
    Set<Integer> set=new HashSet<Integer>();
    while (b != null) {
      set.add(b.data);
      b = b.next;
    }
    while (curr != null) {
      if (set.contains(curr.data)) {
        pre.next = curr.next;
        curr = curr.next;
      } else {
        pre = pre.next;
        curr = curr.next;
      }
    }
    a = head.next;
    return a;
  }
  
  public static void main(String[] args) {
    Node a = new Node();
    Node b = new Node();
    int aa[] = {5,10,20,15,25,30};
    int bb[] = {5,15,35,25};
    Node pre = a;
    a.data = aa[0];
    for (int i = 1; i < aa.length; ++i) {
      Node temp = new Node();
      temp.data = aa[i];
      pre.next = temp;
      pre = temp;
    }
    pre = b;
    b.data = bb[0];
    for (int i = 1; i < bb.length; ++i) {
      Node temp = new Node();
      temp.data = bb[i];
      pre.next = temp;
      pre = temp;
    }
    A1 A = new A1();
    a = A.difference(a, b);
    Node n = a;
    while (n != null) {
      System.out.println(n.data);
      n = n.next;
    }
  }
}


四、9月10日,美团网2014校招研发笔试哈尔滨站

1、链表翻转。给出一个链表和一个数k,比如链表1→2→3→4→5→6,k=2,则翻转后2→1→4→3→6→5,若k=3,翻转后3→2→1→6→5→4,若k=4,翻转后4→3→2→1→5→6,用程序实现

package A4;

import java.util.LinkedList;

class Node{
  int data;
  Node next;
}
public class A1 {
  public void reverse2(Node head,Node tail,int k){
    if(head==null)
      return;
    if(k<2)
      return;
    if(head.next==null)
      return;
    if(head.next.next==null)
      return;
    Node pre=head;
    Node curr=head.next;
    Node next=curr.next;
    while(k--!=0){
      if(pre==head){
        curr.next=tail;
      }
      else{
        curr.next=pre;
      }
      if(next==null)break;
      if(k==0)break;
      pre=curr;
      curr=next;
      next=next.next;  
    }
    head.next=curr;
  }
  public void reverse(Node head,int k){
    Node node=head.next;
    Node pre=head.next;
    A1 A=new A1();
    for(int i=1;i<k;i++){
      node=node.next;
    }
    Node next=node.next;
    A.reverse2(head,node.next, k);
    while(next!=null){
      Node h=pre;
        for(int i=0;i<k;i++){
          if(next==null)break;
          next=next.next;
      } 
        pre=h.next;
        A.reverse2(h,next, k);
    }
  }
  public static void main(String[] args) {
    Node a = new Node();
    int aa[] = {5,10,20,15,25,30};
    Node pre = a;
    a.data = aa[0];
    for (int i = 1; i < aa.length; ++i) {
      Node temp = new Node();
      temp.data = aa[i];
      pre.next = temp;
      pre = temp;
    }
    Node list=new Node();
    list.next=a;
    
    A1 A = new A1();
    A.reverse(list, 2);
    Node n = list.next;
      while (n != null) {
      System.out.println(n.data);
      n = n.next;
    }
  }
}

2、一个m*n的矩阵,从左到右从上到下都是递增的,给一个数elem,求是否在矩阵中,给出思路和代码

package A4;

public class A2 {
  public static boolean isInMatrix(int n, int[][] a) {
    int j = 0;
    for (int i = 0; i < a.length; ++i) {
      while (j < a[i].length) {
        if (a[i][j] == n) {
          return true;
        }
        if (a[i][j] > n) {
          j--;
          break;
        }
        System.out.println(a[i][j]);
        if (j == a[i].length - 1) {
          break;
        }
        ++j;
      }
    }
    return false;
  }
  
  public static void main(String args[]) {
    int a[][] = { {1,2,8,9}, {2,4,9,12}, {4,7,10,13}, {6,8,11,15}};
    for (int i = 0; i < a.length; ++i) {
      for (int j = 0; j < a[i].length; ++j) {
        System.out.print(a[i][j]);
        Integer num = a[i][j];
        for (int k = 0; k < 5 - num.toString().length(); k++) {
          System.out.print(" ");
        }
      }
      System.out.println();
    }
    System.out.println(isInMatrix(15, a));
  }
}

 1、分治法,分为四个矩形,配以二分查找,如果要找的数是6介于对角线上相邻的两个数4、10,可以排除掉左上和右下的两个矩形,而递归在左下和右上的两个矩形继续找,如下图所示:

    2、定位法,时间复杂度O(m+n)。首先直接定位到最右上角的元素,再配以二分查找,比要找的数(6)大就往左走,比要找数(6)的小就往下走,直到找到要找的数字(6)为止,如下图所示:

五、创新工场2014校招

1、求一个正整数N的开方,不能用sqrt函数,精确度在0.001;


用牛顿2分法;

求一个数n的开方就是求y=x^2-n的零点。


一般地,对于函数f(x),如果存在实数c,当x=c时,若f(c)=0,那么把x=c叫做函数f(x)的零点。

解方程即要求f(x)的所有零点。

假定f(x)在区间(x,y)上连续

先找到a、b属于区间(x,y),使f(a),f(b)异号,说明在区间(a,b)内一定有零点,然后求f[(a+b)/2],

现在假设f(a)<0,f(b)>0,a<b  

①如果f[(a+b)/2]=0,该点就是零点,

如果f[(a+b)/2]<0,则在区间((a+b)/2,b)内有零点,(a+b)/2>a,从①开始继续使用

中点函数值判断。

如果f[(a+b)/2]>0,则在区间(a,(a+b)/2)内有零点,(a+b)/2<b,从①开始继续使用

中点函数值判断。

这样就可以不断接近零点。

通过每次把f(x)的零点所在小区间收缩一半的方法,使区间的两个端点逐步迫近函数的零点,以求得零点的近似值,这种方法叫做二分法


package A5;


public class A1 {
  public static float sqrt(int n){
    float high=n;
    float low=0;
    float half=n/2;
    float precision=n;
    while(precision>0.001){
      float s=half*half;
      float temp=half;
      if(s>n){
        high=half;
      }
      if(s<n){
        low=half;
      }
      half=(high+low)/2;
      precision=Math.abs(half-temp);
    }
    return half;
  }
  public static void main(String args[]){
    int n=2;
    System.out.print(sqrt(n));
  }
}

2、A、B两个整数集,设计一个算法,求他们的交集,尽可能高效。

package A6;

import java.util.HashSet;
import java.util.Set;

public class A2 {
  public static void jiaoji(int a[],int b[]){
    Set<Integer> set=new HashSet<Integer>();
    for(int e:a){
      set.add(new Integer(e));
    }
    for(int e:b){
      if(set.contains(e)){
        System.out.print(e+"  ");
      }
    }
  }
  public static void main(String args[]){
    int a[]={1,2,4,6,8,9,3,5};
    int b[]={23,2,42,5,43,6};
    jiaoji(a,b);
  }
}

七、人人网2015校招笔试题。

给定一个有序数组a,长度为len,和一个数X,半段A数组中是否存在两个数,他们的和为X,存在返回true,不存在返回false。

package A7;

public class A1 {
  public static boolean judge(int a[], int x) {
    int low = 0;
    int high = a.length - 1;
    while (low < high) {
      if (a[low] + a[high] == x) {
        return true;
      }
      if (a[low] + a[high] > x) {
        high--;
      }
      if (a[low] + a[high] < x) {
        low++;
      }
      
    }
    return false;
  }
  
  public static void main(String args[]) {
    int a[] = {1,3,4,5,6,9,10,13,15,16};
    System.out.println(judge(a, 4));
    System.out.println(judge(a, 15));
    System.out.println(judge(a, 44));
    System.out.println(judge(a, 2));
    System.out.println(judge(a, 32));
  }
}

2、给定有n个数的数组a,其中超过一半的数为一个定值,在不进行排序,不开设额外数组的情况下,以最高的效率找出这个数;



如果每次删除两个不同的数(不管是不是我们要查找的那个出现次数超过一半的数字),那么,在剩下的数中,我们要查找的数(出现次数超过一半)出现的次数仍然超过总数的一半。通过不断重复这个过程,不断排除掉其它的数,最终找到那个出现次数超过一半的数字。


因此我们可以考虑在遍历数组的时候保存两个值:一个是数组中的一个数字,一个是次数。当我们遍历到下一个数字的时候,如果下一个数字和我们之前保存的数字相同,则次数加1。 如果下一个数字和我们之前保存的数字不同,则次数减1。如果次数为零,我们需要保存下一个数字,并把次数重新设为1。  

    下面,举二个例子:

  • 第一个例子,5,5,5,5,1 :

    不同的相消,相同的累积。遍历到第四个数字时,candidate 是5, nTimes 是4;    遍历到第五个数字时,candidate 是5, nTimes 是3;  nTimes不为0,那么candidate就是超过半数的。 

  • 第二个例子,0,1,2,1,1:

    开始时,保存candidate是数字0,ntimes为1,遍历到数字1后,与数字0不同,则ntime减1变为零,;接下来,遍历到数字2,2与1不同,candidate保存数字2,且ntimes重新设为1;继续遍历到第4个数字1时,与2不同,ntimes减一为零,同时candidate保存为1;最终遍历到最后一个数字还是1,与我们之前candidate保存的数字1相同,ntime加一为1。最后返回的是之前保存的candidate为1。

package A7;

public class A2 {
  public static int find (int a[]){
    int time=1;
    int candidate=a[0];
    for(int i=1;i<a.length;++i){
      if(time==0){
        candidate=a[i];
      }
      if(a[i]==candidate){
        time++;
      }
      if(a[i]!=candidate){
        time--;
      }
    }
    return candidate;
  }
  public static void main(String[] args) {
    int a[]={0,1,1,3,4,6,2,1,1,5,1,4,1,1,1,1,56,1,1,3};
    System.out.println(find(a));
  }
}

八、9月22日,阿里巴巴北邮站

设计一个最优算法查找一个n个元素数组中的最大值和最小值。已知一种需要比较2n次的方法,给出一个更优的算法。请特别注意优化时间复杂度的常数。

package A8;

import java.util.AbstractMap;
import java.util.Map.Entry;

public class A1 {
  public static Entry maxAndMin(int a[]){
    int max=Integer.MIN_VALUE;
    int min=Integer.MAX_VALUE;
    for(int i=0;i<a.length;++i){
      if(a[i]<min){
        min=a[i];
      }
      if(a[i]>max){
        max=a[i];
      }
    }
    Entry<Integer,Integer> entry=new AbstractMap.SimpleEntry<Integer,Integer>(max,min);
    return entry;
  }
  public static void main(String[] args) {
    int a[]={3,5,2,2,76,72,4,3,62,3,46,23,5};
    System.out.println(maxAndMin(a));
  }
}


九、9月24日,去哪儿网2014校招西安站笔试题

给定一个200MB的文本文件,里面存的是IP地址到真实地址信息的映射信息,例如:211.200.101.100北京
然后给你6亿个IP地址,请设计算法快速的打印出所对应的真实地址信息。

package A9;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class A1 {
  public static void main(String[] args) {
    Map<String,String> ipAddress=new HashMap<String,String>();
    try {
      File file = new File("D://ip.txt");
      if (file.isFile() && file.exists()) {
        FileInputStream fs = new FileInputStream(file);
        InputStreamReader is = new InputStreamReader(fs, "GBK");
        BufferedReader reader=new BufferedReader(is);
        String temp=reader.readLine();
        String ip;
        String address;
        while(temp!=null){
          ip=temp.split(" ")[0];
          address=temp.split(" ")[1];
          ipAddress.put(ip, address);
          temp=reader.readLine();
        }
        reader.close();
      }
    } catch (Exception e) {
      System.out.println("读取出错");
    }
    try{
      File file=new File("D://a.txt");
      if (file.isFile() && file.exists()) {
        FileInputStream fs = new FileInputStream(file);
        InputStreamReader is = new InputStreamReader(fs,"GBK");
        BufferedReader reader=new BufferedReader(is);
        String ip=reader.readLine();
        String address;
        while(ip!=null){
          address=ipAddress.get(ip);
          if(address!=null){
            System.out.println(ip+"   "+address);
          }
          else{
            System.out.println(ip+"   unknow");
          }
          ip=reader.readLine();
        }
        reader.close();
      }
    }
    catch(Exception e){
      System.out.println("错误");
    }
  }
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值