1.題目:把乙個陣列最開始的幾個數字移到陣列的末尾,稱為陣列的旋轉,輸入乙個遞增排序的陣列的乙個旋轉,輸出旋轉陣列的最小元素。例如陣列為的乙個旋轉,該陣列的最小值為1.
分析:最簡單的解法是從左到右遍歷陣列,找出最小的,但是時間複雜度是o(n), 沒有利用上排序的特性。乙個遞增的排序陣列在旋轉之後,也是部分有序的,前半部分遞增,後半部分也是遞增。所以可以考慮用二分查詢的方法,在陣列的開始和結束的位置放置兩個指標,如果排除陣列中有相同的數字的話,前半數組的部分比後半數組的部分大,此時,選擇陣列中間的元素,與左邊的指標比較,如果比它大,證明左邊的遞增序列的長度超過整個序列的一半,最小的數字肯定在中間數字的右邊部分,然後將左邊的指標指向當前的中間的位置;同理,如果中間的數字啊比右邊的指標指向的數字小,則最小的數字肯定在該數字的左邊,然後將右邊的指標指向這個位置。這樣一來,查詢的範圍縮小一半,可以在o(lgn)的時間複雜度內找到最小的值。但是還有一些特例。如下圖:
正常的情況:
特殊情況:
原始碼:
#include#includeusing namespace std;
int mininorder(int* numbers, int index1, int index2);
int min(int* numbers, int length)
// 如果下標為index1、index2和indexmid指向的三個數字相等,
// 則只能順序查詢
indexmid = (index1 + index2) / 2;
if (numbers[index1] == numbers[index2] && numbers[indexmid] == numbers[index1])
return mininorder(numbers, index1, index2);
// 縮小查詢範圍
if (numbers[indexmid] >= numbers[index1])
index1 = indexmid;
else if (numbers[indexmid] <= numbers[index2])
index2 = indexmid;
} return numbers[indexmid];
}int mininorder(int* numbers, int index1, int index2)//順序查詢最小的
return result;
}int main()
; result = min(array1, 5);
cout << "the result is " << result << endl;
int array2 = ;//特殊情況
result = min(array2, 5);
cout << "the result is " << result << endl;
int array3 = ;//特殊情況
result = min(array3, 5);
cout << "the result is " << result << endl;
system("pause");
return 0;
}
面試題8 旋轉陣列的最小數字
題目描述 把乙個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。輸入乙個遞增排序的陣列的乙個旋轉,輸出旋轉陣列的最小元素。例如陣列為的乙個旋轉,該陣列的最小值為1。輸入 輸入可能包含多個測試樣例,對於每個測試案例,輸入的第一行為乙個整數n 1 n 1000000 代表旋轉陣列的元素個數。...
面試題8 旋轉陣列的最小數字
旋轉陣列的最小數字 問題描述 將乙個嚴格遞增的數字序列從第i個位置切分,將有半部分挪到左半部分,比如 1,2,3,4,5,6 3,4,5,6,1,2 輸出序列中最小的數字的位置 笨方法是從左到右掃瞄一遍,但是o n 的複雜度肯定是不行的。根據問題描述的性質可知,變換後的序列的第乙個數是大於最後乙個數...
面試題8 旋轉陣列的最小數字
題目描述 題目 把乙個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。輸入乙個遞增排序陣列的乙個旋轉,輸出旋轉陣列的最小元素。例如陣列為的乙個旋轉,該陣列的最小值為1 indexmin初始化為index1是為了防止將排序陣列的前面0個元素搬到最後面 即排序陣列本身 function mi...