効果の対象に
いくつかの要素の配列の先頭には、配列、我々は回転呼んで配列の最後に移動しました。出力回転最小の素子アレイの回転の非減少シーケンスを入力。
たとえば、次の配列{3,4,5,1,2)
である{1,2,3,4,5}
回転。
入力例
{3,4,5,1,2}
出力例
最小値は、アレイです。
問題解決のためのアイデア
それが最小の要素を見つけることであるので、それぞれ、第一の要素と、配列の最後の要素には、2つのポインタを用いて、二分探索を使用することを検討。アレイの回転は、実際には2つのサブアレイに分割することができた後にソートされ、サブアレイ素子の正面の要素は、後で以上サブアレイです。さ 我々はまた、最小の要素は、2つのサブアレイ間の境界線であることを起こることに注意することができます。
最初の要素とそれぞれ配列の最後の要素には、2つのポインタ。
次に、配列の要素:
- サブアレイの正面に位置する中間要素がインクリメントされている場合は1、それはより大きくなるか、第一の要素へのポインタに等しくなければなりません。この時点で、アレイ内の最小要素は、中間要素の背後に配置されます。これは、検索範囲を絞り込むことができ最初の中間要素へのポインタを可能にします。
- 前記中間要素が増分サブアレイの背後に配置されている場合同様に、それ未満、または第2のポインタ要素に等しくなければなりません。この時点で、アレイ内の最小要素は、中間要素の前に配置されるべきです。また、範囲を絞り込むことができます第二の中間の要素へのポインタを置くことができます。
- 最後まで、サイクル1と2を保管してください3。
func MinNumberInArray(array []int) int {
low, high := 0, len(array)-1
// 因为是旋转,所以第一个元素一定大于最后一个元素
// 否则,第一个元素就是那个最小的元素
if array[low] < array[high] {
return array[low]
}
mid = (log + high) / 2
for array[low] >= array[high] {
if high - low == 1 {
mid = high
break
}
mid = (low + htgh) / 2
// 考虑一种特殊情况
// 当 array[low] == array[mid] == array[high] 时
// 只能老老实实按照正常顺序查找
if array[low] == array[mid] && array[mid] == array[high] {
return MinInOrder(array, low, high)
}
if array[mid] >= array[low] {
low = mid
} else {
high = mid
}
}
return array[mid]
}
// 顺序查找
func MinInOrder(array []int, low, high int) int {
min := array[low]
for i := low; i <= high; i++ {
if array[i] < min {
min = array[i]
}
}
return min
}
// 顺序查找中另外一种方法
// 把数组重新拍一下,然后找出第一个元素(但这肯定不是面试官想要的结果)
func MinInOrderII(array []int) int {
sort.Slice(array, func(i ,j int) bool {
return array[i] < array[j]
})
return array[0]
}