有序陣列旋轉的問題

2021-07-13 11:25:04 字數 1516 閱讀 7426

一般情況下我們的第一反應肯定是遍歷此陣列,但這肯定不是我們所期望的,因為此陣列是有序陣列旋轉而成,所以我們此時應該想到用二分法來尋找陣列中的最小值。假設我們給定遞增陣列

旋轉後的陣列有下面幾種形式

通過觀察可以發現,在經過旋轉後的陣列在尋找最小值的過程中0的前面的數總是大於0後面的數,所以我們可以以此為條件,在將範圍縮小為2個數時,後面的數就是最小值,根據此思路**如下:

int minarray(int* a, int n)

mid = (start + end) / 2;

//如果a[start],a[mid],a[end]相等時,只能遍歷尋找最小值

if (a[mid] == a[start] && a[mid] == a[end])

++start;

}return min;

} if (a[mid] >= a[start])

else if (a[mid] <= a[end])

}return a[mid];

}

上面的程式已經將一種特殊情況給處理了,例如下面這種例子

此時若直接進行比較,將會出現將最小值跳過的情況,所以我們在此種情況下只能採取遍歷尋找最小值。

我們也可以使用下標的方式來實現尋找最小值,思路和上面的程式一樣,**如下:

int minarray2(int* a, int n)

++start;

}return min;

} if (a[mid] >= a[start] && a[mid] <= a[end]) //此時陣列有序,直接返回陣列下標0

if (a[mid] >= a[start])

else if (a[mid] <= a[end])

}if (a[start] > a[end])

return a[start];

}

上面是求去旋轉有序陣列的最小值,求最大值的思路和最小值的一樣,只需要在迴圈結束返回時返回那個較大值即可。

實現在乙個旋轉有序陣列中尋找乙個數並返回下標,很多人的第一反應肯定是直接遍歷,但這樣的話有序陣列旋轉的特性沒有得到應用,所以我們需要分析旋轉有序陣列的特點,例如下面旋轉有序陣列

通過觀察上面的陣列我們可以發現無論陣列如何旋轉,陣列分成兩個子陣列時,乙個肯定是有序的,所以我們可以利用此特性來實現尋找乙個特定的數,每次將給定數值通過和有序陣列的首尾兩個值對比,來判斷此數是否存在在這個陣列中,如果在的話,將此陣列遞迴,若不在,將另乙個陣列遞迴,重複此過程,直至首尾元素下標相同,或尋找到此給定數值。

依據上面的思路實現的**如下:

int search(int* a, int n, int x)

else if (a[mid] > a[start])

else

}else if (a[end] > a[mid])

else

}else

}return -1;

}

刷題筆記 旋轉有序陣列

leetcode 四道旋轉有序陣列相關的題 1 找到陣列的最小值 leetcode154 陣列有重複 leetcode153 陣列無重複 和nums right 比較 nums mid nums right 左邊有序 left mid 1 跟左邊比,可能會錯過最小值 兩個問題共享同乙份 def fi...

有序陣列的連線問題

1.前言 昨天碰到一道關於如何解決有序陣列的連線問題,這是乙個很常見的問題。但是這裡要考慮到 的效率問題,因為要連線的陣列都是有序的,這是乙個非常重要的前提條件。2.簡單但效率不高的演算法 我首先想到的是使用內建的concat方法,然後再對其進行排序,這種方法完全沒有考慮到陣列是有序的前提條件,如下...

在旋轉有序陣列中查詢元素

1.題目 給定乙個旋轉的有序陣列,比如是旋轉之後得到的,在陣列中查詢是否存在元素key。要求時間複雜度為o lgn 假定陣列中不存在重複元素。2.分析 從上面的選擇陣列可以發現,array middle 將陣列分成兩段,兩段中必有一段是有序的。這樣就可以使用二分查詢了。乙個變形的二分查詢。3.1 i...