再說一道面試題及相應的測試[一個有序數組A[n],從中間某一點截斷, 把它前半部分接到后半部分的后面形成B[n], 請從B[n]找到A[n]截斷位置]




面試題: 一個有序數組A[n],從中間某一點截斷, 把它前半部分接到后半部分的后面形成B[n], 請從B[n]找到A[n]截斷位置

分析:
  1. 這個數組A必須是有序的, 有序就必須考慮兩種情況升序和降序.  假設所有都平序, 應該不滿足需要. 比如全為1
  
 
  2. 這個找到截斷的位置,應該可以用二分法來做

  3. 數組的個數應該必須大於等於2. 2個數的數組是可以的. 比如3,4.從4處截斷可以形成4,3

  
從測試來說, 我們可以考慮以下例子: 

1.  只有1個數的數組

2. 只有2個數的數組

3. 只有一個轉折的數組(升序)

4. 只有一個轉折的數組(降序)

5. 不止一個轉折的數組

6. 全升的數組

7. 全降的數組 
8. 只有一個轉折的數組,轉折點左右重復數
9. 只有一個轉折的數組,非轉折點有重復數

如何判斷數組A是升序還是降序呢? 其實 只要判斷第一個數和最后一個數的大小就可以了.  如果首數大於或等於最后數, 原數組就是升序. 否則降序


不說了,上程序 (C#):

       public static int FindIndexFromArray(int[] bArray)
        {
            //Detect if A[n] is ASC or DSC order
            bool isAscOrder = bArray[0] >= bArray[bArray.Length - 1];

            //Use Binary Search
            int low = 0;
            int high = bArray.Length - 1;
            int mid = -1;
            while (true)
            {
                if ((low + high) / 2 != mid)
                {
                    mid = (low + high) / 2;
                    if (isAscOrder && bArray[low] <= bArray[mid]
                        ||
                        !isAscOrder && bArray[low] >= bArray[mid]
                        )
                    {
                        low = mid;
                    }

                    if (isAscOrder && bArray[mid] <= bArray[high]
                    ||
                    !isAscOrder && bArray[mid] >= bArray[high]
                    )
                    {
                        high = mid;
                    }

                    if (low + 1 == high)
                    {
                        break;
                    }
                }
                else
                {
                    throw new ArgumentException("The provided array did not match the rule. Please check!");
                }
            }

            return bArray.Length - low - 2;
        }


測試程序: 從數組A構造數組B
               public static int[] ConstructArrayB(int[] aArray, int index)
        {
            if (aArray.Length < 2 || index > aArray.Length - 2)
            {
                throw new ArgumentException();
            }

            int[] bArrary = new int[aArray.Length];

            for (int i = 0; i <= index; i++)
            {
                bArrary[i - index + aArray.Length - 1] = aArray[i];
            }

            for (int i = index + 1; i < aArray.Length; i++)
            {
                bArrary[i - index - 1] = aArray[i];
            }

            return bArrary;
        }

        public static void Print(int[] array)
        {
            foreach (int c in array)
            {
                Console.Write(c + " ");
            }
            Console.WriteLine();
        }

        static void Main(string[] args)
        {
            int[] a = { 1, 1, 2, 3, 3, 4,5,12,30 };
            Console.WriteLine("數組A");
            Print(a);
            int index = 2;
            Console.WriteLine("從{0}折斷數組A", index);
            int[] b = ConstructArrayB(a, index);
            Console.WriteLine("數組B:");
            Print(b);
            int index2 = FindIndexFromArray(b);
            Console.Write("從數組B得到A的折斷點:{0}", index2);
            Console.Write("判斷算法正確與否:{0}", index == index2 );
        }


最近 再次想了想, 中間程序 可以簡化
        public static int FindIndexFromArray(int[] bArray)
        {
            //Detect if A[n] is ASC or DSC order
            bool isAscOrder = bArray[0] >= bArray[bArray.Length - 1];

            //Use Binary Search
            int low = 0;
            int high = bArray.Length - 1;
            int mid = -1;
            while (low <= high)
            {
                mid = (low + high) / 2;
                if (isAscOrder && bArray[mid] > bArray[mid + 1]
                    ||
                    !isAscOrder && bArray[mid] < bArray[mid + 1]
                    )
                {
                    return bArray.Length - mid - 2;
                }

                if (isAscOrder && bArray[mid] <= bArray[high]
                    ||
                    !isAscOrder && bArray[mid] <= bArray[high]
                 )
                {
                    high = mid;
                }
                else
                {
                    low = mid;
                }
            }

            return bArray.Length - mid - 2;
        }


  
  




注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com