一道微软算法题的java解法

原创 2003年04月07日 10:26:00

上回看到一道微软的算法题,题目大概是说:有一个很大的整型数组,我们怎样能够找到一个不在这个数组中的值。
假设一个数组的大小很大(比如说35000个值),我们知道整型的取值范围在某种c/c++编译器中是16位的,也就只能到65536。那么怎样才能通过最少的代价找到不在这个数组中的整型值呢?!

解答:
1、我们可以利用像数数字一样的算法,来解答这个问题。比如说我们数1到10的时候,如果1到10都是连续的话,那么我们可以肯定在这个中间是不会存在不在这个范围类的值了,具体到这个环境中,我们同样可以这样考虑,假设我们把数组遍历一遍,把其中所有能够连续的数值都去掉,那么那些连续数值中间的不连续地段,就是我们要找的值的所在。
2、因为java语言对于数据结构的良好封装,这道题的java解答很简单也容易。首先我们描述下面一个数据结构:
/*
 * Created on 2003-4-6
 *
 * To change this generated comment go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
package bia.arithmetic;

import java.io.PrintStream;


/**
 * @author Administrator
 *
 * To change this generated comment go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
public class NumberNode {
 int value ;
 boolean hasLeft ;
 boolean hasRight ;
 
 NumberNode next,prev ;
 
 public void print(PrintStream out){
  String s = String.valueOf(value) ;
  if (hasLeft){
   s = "-" + s ;
  }
  else {
   s = " " + s ;
  }
  if (hasRight){
   s = s + "-" ;
  }
  else {
   s = s + " " ;
  }
  out.print(s) ;
 }
 
 public NumberNode(){
  value=0 ;
  hasLeft = false ;
  hasRight = false ;
 }
 /**
  * @return boolean
  */
 public boolean isHasLeft() {
  return hasLeft;
 }

 /**
  * @return boolean
  */
 public boolean isHasRight() {
  return hasRight;
 }

 /**
  * @return NumberNode
  */
 public NumberNode getNext() {
  return next;
 }

 /**
  * @return NumberNode
  */
 public NumberNode getPrev() {
  return prev;
 }

 /**
  * @return int
  */
 public int getValue() {
  return value;
 }

 /**
  * Sets the hasLeft.
  * @param hasLeft The hasLeft to set
  */
 public void setHasLeft(boolean hasLeft) {
  this.hasLeft = hasLeft;
 }

 /**
  * Sets the hasRight.
  * @param hasRight The hasRight to set
  */
 public void setHasRight(boolean hasRight) {
  this.hasRight = hasRight;
 }

 /**
  * Sets the next.
  * @param next The next to set
  */
 public void setNext(NumberNode next) {
  this.next = next;
 }

 /**
  * Sets the prev.
  * @param prev The prev to set
  */
 public void setPrev(NumberNode prev) {
  this.prev = prev;
 }

 /**
  * Sets the value.
  * @param value The value to set
  */
 public void setValue(int value) {
  this.value = value;
 }

}
然后,我们利用这个结构构造一个NumberList链表,来处理排序和依次读取的操作,在这个过程中,将中间连续的部分屏蔽掉,只留下连续的边界。

/*
 * Created on 2003-4-6
 *
 * To change this generated comment go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
package bia.arithmetic;

import java.io.PrintStream;

/**
 * @author Administrator
 *
 * To change this generated comment go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
public class NumberList {
 NumberNode first;

 public void print(PrintStream out){
  out.println("======Begin print List======") ;
  NumberNode p = first ;
  while (null!=p){
   p.print(out) ;
   p = p.getNext() ;
  }
  out.println("/n======End print List======") ;
 }
 
 public NumberList() {
 }

 public NumberNode getFirst() {
  return first;
 }

 public void addNumber(int number){
  NumberNode node = new NumberNode() ;
  node.setValue(number) ;
  addNode(node) ;
 }
 /**
  * 增加一个节点的方法
  * @Renzhichao
  * @param node
  */
 public void addNode(NumberNode node) {
  if (first == null) {
   first = node;
   first.setPrev(null);
   first.setNext(null);
   first.setHasLeft(false) ;
   first.setHasRight(false) ;
  }
  else {
   NumberNode tmp = first;
   NumberNode p = tmp;
   while (tmp.getValue() < node.getValue() && tmp.getNext() != null) {
    p = tmp;
    tmp = tmp.getNext();
   }
   if (tmp.getValue()<node.getValue()){
    //node插在链表的结尾。
    tmp.setNext(node) ;
    node.setPrev(tmp) ;
    node.setNext(null) ;
    if (tmp.getValue()+1==node.getValue()){     
     tmp.setHasRight(true) ;
     node.setHasLeft(true) ;
     if (tmp.isHasLeft()&&tmp.isHasRight()){
      p.setNext(node) ;
      node.setPrev(p) ;
      tmp=null ;      
     }
    }
   }
   else if (tmp.getValue()>node.getValue()){
    //node插在链表的中央。    
    if (tmp==first){
     //首先判断tmp是不是first
     first = node ;
     first.setHasLeft(false) ;
     first.setHasRight(false) ;
     first.setNext(tmp) ;
     first.setPrev(null) ; 
     tmp.setPrev(node) ;    
     if (first.getValue()+1==tmp.getValue()){      
      first.setHasRight(true) ;
      tmp.setHasLeft(true) ;
      if (tmp.isHasLeft()&&tmp.isHasRight()){
       //去掉tmp节点
       first.setNext(tmp.getNext()) ;
       tmp = null ;
      }
     }
    }
    else {     
     if (p.getValue()+2 == tmp.getValue()){
      //判断是不是p和tmp可以连续了
      p.setHasRight(true) ;
      tmp.setHasLeft(true) ;
     }
     else if (!p.isHasRight()&&!tmp.isHasLeft()){
      p.setNext(node) ;
      tmp.setPrev(node) ;
      node.setPrev(p) ;
      node.setNext(tmp) ;
      if (p.getValue()+1 == node.getValue()){
       p.setHasRight(true) ;
       node.setHasLeft(true) ;
      }
      else if (node.getValue()+1==tmp.getValue()){
       node.setHasRight(true) ;
       tmp.setHasLeft(true) ;
      }
     }
    }
   }
  }
 }
}

算法题总结+解法

原题转载自:http://www.cnblogs.com/xwdreamer/archive/2011/12/13/2296910.html 解法为原创,红色字体标出。 1.把...
  • liuxialong
  • liuxialong
  • 2014年12月10日 13:01
  • 1520

一道初等平面几何竞赛题的暴力解法

问题一道初中数学竞赛,平面几何题计算: 这里改成了证明题,反正思路是一样的。暴力解法暴力破解的方法是怎样的?首先,代数方法对很大一部分这类问题都是可以算的。但是应该注意下面几点: 1. 并不是所有...
  • stereohomology
  • stereohomology
  • 2017年08月14日 11:33
  • 351

每日一道算法题——1

求字符串字串的长度。
  • q1242027878
  • q1242027878
  • 2017年02月07日 13:06
  • 584

一道解决的非常漂亮的算法题

这是多年以前做的一道题目,原题来自软件报或者电脑报 ,我记不清了。解决这个题目有一个关键的步骤,就是要求一个整数在一个整数三角阵中的坐标。这篇blog就是讨论这个求坐标的问题,不是讨论那个报纸上的题目...
  • BinaryTreeEx
  • BinaryTreeEx
  • 2007年05月04日 10:12
  • 4137

曾经做的一道算法题,到目前为止,我觉得是最好的一道算法题了。

某学校进行打字比赛,比赛主要考查选手在规定时间内正确输入的字数。但问题是,如何确定每一个输入的字是否是正确的(即是否与原稿相同),因为完全存在选手错字、漏字和增字的情况,如:原稿为“abcde”,打字...
  • limingchuan123456789
  • limingchuan123456789
  • 2012年08月22日 15:17
  • 1186

2017微软面试算法题回顾

惨痛的回忆= = 1.求一个数组中的逆序对数 思路:O(n2)的解法很明显,暴力破解即可。但这肯定不是面试官要的答案,很明显这样的题是找至少O(nlogn)的解法。 考虑使用归并...
  • dreamerleague
  • dreamerleague
  • 2017年04月25日 12:15
  • 503

微软100题算法解答

本文是旨在实践”用变量、循环
  • binling
  • binling
  • 2014年05月14日 00:06
  • 655

每天一道算法题(24)——自定义幂函数pow

double myPower(double base, int exponent){ if(exponent==0) return 1; if(exponent==1) return ba...
  • qianhen123
  • qianhen123
  • 2015年06月25日 16:13
  • 641

史上最难的一道Java面试题

求下面这段程序的运行结果public class TestSync2 implements Runnable{ int b=100; synchronized void m1() ...
  • weixin_38553453
  • weixin_38553453
  • 2017年06月08日 15:31
  • 619

微软算法100道题

题目: n个数字(0,1,…,n-1)形成一个圆圈,从数字0开始, 每次从这个圆圈中删除第m个数字(第一个为当前数字本身,第二个为当前数字的下一个数字)。 当一个数字删除后,从被删除数字的下一个...
  • ice_time1
  • ice_time1
  • 2015年11月20日 16:10
  • 177
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:一道微软算法题的java解法
举报原因:
原因补充:

(最多只允许输入30个字)