终于搞清楚了C#二进制的一些关键操作了,解决了微软面试题,求数组中两两之差绝对值最小的值O(N)最少内存限制的问题!

 终于搞清楚了C#二进制的一些关键操作了,解决了微软面试题,求数组中两两之差绝对值最小的值O(N)最少内存限制的问题!

研究了好几天,写出来一个看起来象O(n)的算法,O(nlog)就不用写了.
思路是桶排序O(N)复杂度,为了节省空间,采用了Byte[]数组,1个byte代表8个数字的有无.
回头整理公布一下C#二进制运算的一些重要操作.
C# code
using System; namespace MinABS { class Program { static void Main(string[] args) { int n = 100; int[] a = new int[n]; Random rand = new Random(); int min = int.MaxValue; int max = int.MinValue; Console.WriteLine("产生了" + n + "个数据的实验数组,"); Console.WriteLine("本程序适用于int.MinValue到int.MaxValue范围,请自行修改输入的量和范围"); for (int i = 0; i < n; i++) { //赋值并且取到最大最小值 //a[i] = rand.Next(int.MinValue, int.MaxValue); a[i] = rand.Next(-100, 100); if (a[i] < min) { min = a[i]; } if (a[i] > max) { max = a[i]; } Console.Write(a[i] + " "); } Console.WriteLine(); Console.WriteLine("在O(n)内得到最大最小分别是:"); Console.WriteLine(max + "" + min); long offset = (long)max + Math.Abs((long)min); //规划数组的长度。每个byte有8位长 int len = (int)(offset >> 3) +1 ; Byte[] B = new Byte[len]; int kkkk = 0; bool IsSame = false;//是否有重合点标记 //O(n)的时间内分配到了Byte[]中。 for (int i = 0; i < n; i++) { offset = (long)a[i] - (long)min; int index = (int)(offset >> 3); int temp = B[index]; //把末k位变成1 //把右数第k位变成1 例如:(00101001->00101101,k=3) x | (1 << (k-1)) int tempOffSet = (1 << ( (int)(offset & 7) ) ); //判断重合 if (!IsSame) { kkkk = temp & tempOffSet; if ((temp & tempOffSet) >= 1) { IsSame = true; //如果0算最小距离就在这里退出吧。本代码判断重合,但没把0作为结果。 } } int bbb = B[index]; B[index] |= (Byte)(tempOffSet); int aaa = B[index]; } //最小距离初始为最大。 Console.WriteLine("在O(n)的时间内分配到了Byte[]中,正在计算最小距离,请稍候。。。。。"); long minABS = long.MaxValue; long lastIndex = -1; //在常数范围内循环,复杂度不增加。最坏的情况是32*int.MaxValue次。 for (int i = 0; i < B.Length; i++) { //if (B[i] == 0) { continue; } //在常数范围内循环,复杂度不增加。 for (int k = 0; k < 8; k++) { if (((B[i] >> k) & 1) == 1) { if (lastIndex >= 0) { long temp = ((long)i << 3) + k - lastIndex; if (temp < minABS) { minABS = temp; Console.WriteLine("目前得到了最小距离:" + minABS); } } lastIndex = (i << 3) + k; } } } if (IsSame) { Console.WriteLine("有重合点"); } else { Console.WriteLine("无重合点"); } Console.WriteLine("不考虑重合最小距离是:" + minABS); Console.WriteLine("总复杂度是:O(n)"); Console.ReadLine(); } } }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章