面试问题集锦

来源:互联网 发布:java表格 插件 编辑:程序博客网 时间:2024/05/21 13:20


1.1        在成对存在的数组中(即数组中的每个数必然存在另一个与其值相等的一个数),被程序员误插入了一个数(即该数在这个数组中唯一),如何找出这个数?  

 

答案:将所有数化为二进制,做异或。

 

   1.2        在成对存在的数组中(即数组中的每个数必然存在另一个与其值相等的一个数),被程序员误插入了两个数(即这两个数在这个数组中都是唯一),如何找出这两个数?  

 

答案:异或所有数,所得结果相当于混入的这两个数的异或,取其不为0的某一位,按照这一位将数组元素分成两组(一组为0,一组为1),两组组内异或,分别得到这两个数。题目来源剑指offer《数组中只出现一次的数字》

//num1,num2分别为长度为1的数组。传出参数//将num1[0],num2[0]设置为返回结果public class Solution {    public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {        //任何一个数异或自己都为0,最后只剩下两个出现一次的数的异或值        int s=0;        for(int i=0;i<array.length;i++)        {        s=s^array[i];        }        int indexOf1=FindFirstBitIs1(s);        num1[0]=0;        num2[0]=0;        for(int j=0;j<array.length;j++)        {        if(isBit1(array[j],indexOf1)==1)        num1[0]^=array[j];        else        num2[0]^=array[j];        }    }private  int isBit1(int i, int indexOf1) {// TODO Auto-generated method stubi=i>>indexOf1;       return (i&1);}private  int FindFirstBitIs1(int s) {// TODO Auto-generated method stubint indexBit=0;while((s&1)==0){indexBit++;s=s>>1;}return indexBit;}      }

 

   2.1        给定一个数组a[],一次遍历在其中找出最大(最小)的元素。  

 

答案:冒泡排序。

   2.2        给定一个数组a[],找出其中某两个数的和等于给定的一个数M。  

      

答案:首先快排(从小到大),然后头尾两个指针,若头尾指向的数之和大于M,尾指针减减,否则头指针加加。

   2.3        给定一个数组a[],在其中找k个数(k>=2),使得其和等于给定的一个数M,没有返回false。 (个人还没验证) 

 

答案:动态规划-01背包问题。

  3.1        四人过桥问题:速度设为v1,v2,v3,v4,满足v1>v2>v3>v4单独过河时间满足:t1<      t2 < t3 < t4,此时正在下雨,四人只有一把伞,于是两人共有一把伞过河,过桥速度以最慢的为主,过河后需要其中一个送伞回去,问如何安排过河时间最短?  

 

答案:方案一:正常思维会认为v1速度最快,让他每次回头送伞最合适,于是v1分别与其他人过河再回头送伞,总时间:t2+t3+t4+2*t1。

方案二:考虑到v1>v2>>>v3>v4(即v1、v2远远大于v3、v4),可以让v1、v2先过河,v1回头送伞,v3、v4一起过河,v2回头送伞,然后v1、v2再过河,

总时间:t2+t1+t4+t2+t2。

综合考虑,本题回答动态规划为最佳答案。


4.二叉树按行打印  

 

答案:这是一道老题了,首先注意是按行打印,判断何时需要换行,实现的时候需要一个队结构,我是用链表实现的,其次改造node结点,在原基础上加一个line标记,表示该结点是第几行的,具体实现:初始化:树根入队,定义变量current(当前行)为1,打印树根,然后判断树根的左孩子和有孩子是否为空,依次入队,递归调用。

伪代码:  current=1;front=T; rear=front.next;

           Public A( root) {

              If(front.next==null){return ;}//树根为空,退出

              If(root.flag==(current+1)){ 换行}//当前结点的标志位等于当前行数加一,该换行了;

              Print(root.data);  //打印值

              If(root.left!=null){ //加入左孩子

                 rear.flag=Root.flag+1; //标记结点行数

                 rear=Root.left;

                 Rear=Rear.next;

                }

              If(root.right!=null){ //加入右孩子

                 rear.flag=Root.flag+1; //标记结点行数

                 rear=Root.right;

                 Rear=Rear.next;

                }

              A(front);  //递归调用

           }


剑指offer原题《从上往下打印二叉树》

思路:利用队列思想

import java.util.ArrayList;import java.util.Queue;import java.util.LinkedList;/**public class TreeNode {    int val = 0;    TreeNode left = null;    TreeNode right = null;    public TreeNode(int val) {        this.val = val;    }}*/public class Solution {  public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {ArrayList<Integer> list = new ArrayList<Integer>();if (root == null)return list;Queue<TreeNode> queue = new LinkedList<TreeNode>();queue.offer(root);while (!queue.isEmpty()) {root = queue.poll();if (root.left != null)queue.offer(root.left);if (root.right != null)queue.offer(root.right);list.add(root.val);}return list;}}

5.给你四个坐标(x,y)判断是否为矩形?  

 

答案:取一个点,与其他三个点求距离,看是否满足勾股定理,然后计算余弦值,只要存在负数,就说明有钝角,return FALSE,否则为真。


6.给定一个数组,从中取三个值,将数组分成四个部分(不包含这三个值),使得四个部分每个部分之和相等。如以下数组:1213151,取出的三个值分别为:2,3,5。  题目来源阿里巴巴的春招实习生上机测试题

 

答案:暴力法:设置三个指针,i1、i2、i3,四个和值:sum1、sum2、sum3、sum4,分别表示0~i1(不含i1),0~i2(不含i1,i2),0~i3(不含i1,i2,i3),数组总和(不含i1,i2,i3),三层循环,最终找出满足一下关系式:4sum1=2sum2=(4/3)    * sum3=sum4。


原创粉丝点击