一般情況下我們的第一反應肯定是遍歷此陣列,但這肯定不是我們所期望的,因為此陣列是有序陣列旋轉而成,所以我們此時應該想到用二分法來尋找陣列中的最小值。假設我們給定遞增陣列
旋轉後的陣列有下面幾種形式
通過觀察可以發現,在經過旋轉後的陣列在尋找最小值的過程中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...