微软面试题,求数组中两两之差绝对值最小的值。O(n)

微软的面试题,我做过。鸽巢原理。
using System;
using System.Linq;
using System.Collections.Generic;
namespace ConsoleApplication1
{
  class Program
  {
  static Random Rand = new Random();

  static void Main(string[] args)
  {
  int count = 10000;
  List<int> Input = new List<int>();
  for (int i = 0; i < count; i++)
  {
  Input.Add(Rand.Next(int.MinValue, int.MaxValue));
  }

  ulong re = PigeonNest(Input, ulong.MaxValue);
  Console.WriteLine(re);
  Console.WriteLine("-------------");
  Console.Read();
  }

  //鸽巢原理。
  static ulong PigeonNest(List<int> List, ulong MinResult)
  {
  switch (List.Count)
  {
  case 0:
  case 1:
  return MinResult;
  case 2:
  return ABS(List[0], List[1]);
  default:
  break;
  }
  int min = List.Min();
  //确定桶的大小。
  int width = (int)Math.Ceiling((double)(List.Max() - min) / List.Count);
  //不可能比1还小了。
  if (width == 1) { return 1ul; }
  //把数据丢到桶里。
  Dictionary<int, NumbersInfo> EachNestNum = new Dictionary<int, NumbersInfo>();
  foreach (int n in List)
  {
  int Key = Convert.ToInt32(Math.Ceiling((double)(n - min) / width));
  if (!EachNestNum.ContainsKey(Key))
  {
  EachNestNum.Add(Key, new NumbersInfo(Key));
  }
  EachNestNum[Key].Add(n);
  }
  //找到所有桶里,和相邻两桶的最大最小值距离,三个数中最近的。
  foreach (int Key in EachNestNum.Keys)
  {
  MinResult = Min(MinResult, EachNestNum[Key].minresult(EachNestNum, MinResult));
  }
  return MinResult;
  }
  class NumbersInfo
  {
  public NumbersInfo(int k)
  { key = k; }
  private List<int> List = new List<int>();
  private int key;
  public int max = int.MinValue;
  public int min = int.MaxValue;
  public int count { get { return List.Count; } }
  public ulong minresult(Dictionary<int, NumbersInfo> EachNestNum, ulong re)
  {
  //在三个数中选最小的。  
  //当命中数大于1的时候,递归这个过程。由于迅速收敛,故复杂度忽略不计。
  if (List.Count > 1)
  {
  re = PigeonNest(List, re);
  }
  if (EachNestNum.ContainsKey(key - 1))
  {
  re = Min(ABS(EachNestNum[key].min, EachNestNum[key - 1].max), re);
  }
  if (EachNestNum.ContainsKey(key + 1))
  {
  re = Min(ABS(EachNestNum[key].max, EachNestNum[key + 1].min), re);
  }
  return re;
  }
  public void Add(int x)
  {
  List.Add(x);
  if (x > max) { max = x; }
  if (x < min) { min = x; }
  }
  }


  static ulong ABS(int x, int y)
  {
  //三分。
  switch (x.CompareTo(y))
  {
  case -1:
  return (ulong)y - (ulong)x;
  case 1:
  return (ulong)x - (ulong)y;
  }
  return 0ul;

  }

  static ulong Min(ulong x, ulong y)
  {
  if (x > y) { return y; }
  return x;
  }
  }
}
posted @ 2011-07-10 01:30  CSDN大笨狼  阅读(1020)  评论(1编辑  收藏  举报