終於搞清楚了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(); } } }

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