LeetCode33-搜尋旋轉排序陣列
阿新 • • 發佈:2018-12-10
昨天參加學院舉辦的演算法比賽
從上午10點一直考到下午3點
唯一的感受就是
中午發的兩袋皇冠蛋糕和牛奶
真TM的好吃!!!
33-搜尋旋轉排序陣列
假設按照升序排序的陣列在預先未知的某個點上進行了旋轉。
( 例如,陣列 [0,1,2,4,5,6,7]
可能變為 [4,5,6,7,0,1,2]
)。
搜尋一個給定的目標值,如果陣列中存在這個目標值,則返回它的索引,否則返回 -1
。
你可以假設陣列中不存在重複的元素。
你的演算法時間複雜度必須是 O(log n) 級別。
示例 1:
4,5,6,7,0,1,2]
示例 2:
4,5,6,7,0,1,2]
這一題出題人的意思其實是很好,想讓我們用二分法找值,但是檢測系統有點辣雞啊!直接用個index()找值也是ok的,而且執行效率很快。
直接找值程式碼如下:
class Solution: def search(self, nums, target): """ :type nums: List[int] :type target: int :rtype: int """ if len(nums) == 0 or target is None: return -1 if target in nums: return nums.index(target) else: return -1 if __name__ == "__main__": nums = [4,5,6,7,0,1,2] target = 3 result = Solution().search(nums, target) print(result)
這個的執行效率在90%以上。
但是為了不辜負出題人的一番心血,我們還是得按照題目的意思來好好做。因為題目規定:演算法時間複雜度必須是 O(log n) 級別,所以我們很容易想到用二分法來解題。因為給定的陣列其實是兩段升序陣列拼接起來的,這就給了我們一箇中間值與起始值和終點值的大小關係。還有一點關鍵就是:左邊的升序陣列一定是比右邊的升序陣列的值要大。大家一想想就清楚了,所以如果中間值比終點值要大,說明中間值肯定是在第一個升序數組裡面;如果要小,說明一定是在第二個升序數組裡,以此類推。挺簡單的,直接看程式碼吧!
程式碼如下:
class Solution: # 因為題目要求時間複雜度為O(logN),故想到二分法 # 首先得找到二段旋轉排序陣列的分解值 # 找到分界值後,即可分別對兩段陣列做二分法搜尋 def search(self, nums, target): """ :type nums: List[int] :type target: int :rtype: int """ # 只要給定的nums陣列或者給定的target目標值為空,說明查無此值 if len(nums) == 0 or target is None: return -1 # 首先查詢分界值,也是採用二分法查詢,分別定義起始點start和終點end start = 0 end = len(nums) - 1 binart_index = 0 while start < end: mid = (start+end)//2 if nums[mid] >= nums[mid+1]: binart_index = mid break if nums[mid] > nums[end]: start = mid else: end = mid print("binart_index", binart_index) # 定義查詢target的目標值的下標值初始值為-1 target_index = -1 nums_left = nums[:binart_index+1] nums_right = nums[binart_index+1:] if len(nums_left) > 0: print("nums_left", nums_left) target_index = self.binary_search(nums_left, target) print("target_index", target_index) if target_index < 0 and len(nums_right) > 0: print("nums_right", nums_right) target_index = self.binary_search(nums_right, target) print("target_index", target_index) if target_index > -1: target_index += binart_index + 1 return max(target_index, -1) # 二分法在nums數組裡查詢目標值 def binary_search(self, nums, target): start = 0 end = len(nums) - 1 target_index = -1 while start <= end: mid = (start+end)//2 if nums[mid] == target: target_index = mid break elif nums[mid] > target: end = mid -1 else: start = mid + 1 print("mid", mid) return target_index if __name__ == "__main__": nums = [3, 4, 5, 0, 1] target = 2 result = Solution().search(nums, target) print(result)
執行效率一般,在40%左右。