關於旋轉排序陣列leetcode中共有4道題目,思路都是基於二分查詢。
假設按照公升序排序的陣列在預先未知的某個點上進行了旋轉。
( 例如,陣列 [0,1,2,4,5,6,7] 可能變為 [4,5,6,7,0,1,2] )。
找最小值和普通搜尋兩種
找最小值問題
1.假設陣列中不存在相同元素(153題 中等)
示例:
輸入: [3,4,5,1,2]
輸出: 1
思路:
每次將mid和hi位置的數比較即可判斷最小值所在的區間
**:
public int findmin(int nums) else
}return nums[l];
}
2.假設陣列中存在相同元素(154題 困難)
示例:
輸入: [1,1,1,0,1]
輸出: 0
思路:
如果陣列元素允許重複的話,那麼就會出現乙個特殊的情況:nums[l] == nums[m] == nums[h],那麼此時無法確定解在哪個區間,需要切換到順序查詢。例如對於陣列 ,l、m 和 h 指向的數都為 1,此時無法知道最小數字 0 在哪個區間。
**:
public int findmin(int nums)
}return nums[l];
}
搜尋問題
搜尋乙個給定的目標值,如果陣列中存在這個目標值,則返回它的索引,否則返回 -1
1.假設陣列中不存在相同元素(33題 中等)
例項:
輸入: nums = [4,5,6,7,0,1,2], target = 0
輸出: 4
思路:
可以基於153題,第一次二分查詢找到最小值的位置(翻轉點的位置)。有了最小值的索引便有個乙個對映關係,mid和realmid。第二遍的二分查詢就是乙個常規的二分查詢,但要考慮對映關係,即每次拿realmid的值比較而不是mid位置的值。
**:
public int search(int nums, int target) else
}return -1;
}
2.假設陣列中存在相同元素(81題 中等)
示例:
input: nums = [2,5,6,0,0,1,2], target = 0
output: true
思路:
這題相當於在154題的基礎上,
第一步,用154題的函式找到存在重複元素陣列中最小值(翻轉點)的位置;
第二步,參考1的做法,通過對映關係完成一次常規二分查詢。
**:public boolean search(int nums, int target) else if (nums[realmid]>target)else
}return false;
}public int find(int nums,int l,int h)
}return l;
}public int findminindex(int nums) {
int l=0,h=nums.length-1;
while (l旋轉排序陣列中的問題無非就是查詢問題,而排序陣列中的查詢問題採用二分查詢效率最高,所以要盡量利用其中的順序關係轉化為二分查詢來解決。
對於找最小值(旋轉點)問題,又可以分為無重複元素和有重複元素;對於無重複元素找最小值問題,每次將mid位置元素和h位置元素比較;對於有重複,注意特例類似[1,1,1,0,1,1],出現特例時就要區域性利用順序查詢來繼續查詢了,所以複雜度會由o(logn)退化到o(n)。
對於搜尋問題,第一步都是解決找旋轉點的問題,根據有無重複元素採用不同函式。第二步,在找到旋轉點後,便有了「mid」和「realmid」的對映關係,就可以轉化為普通二分查詢搜尋問題。
LeetCode 尋找旋轉排序陣列中的最小值II
假設按照公升序排序的陣列在預先未知的某個點上進行了旋轉。例如,陣列 0,1,2,4,5,6,7 可能變為 4,5,6,7,0,1,2 請找出其中最小的元素。注意陣列中可能存在重複的元素。示例 1 輸入 1,3,5 輸出 1 示例 2 輸入 2,2,2,0,1 輸出 0 說明 這道題是 尋找旋轉排序陣...
Leetcode 搜尋旋轉排序陣列
假設按照公升序排序的陣列在預先未知的某個點上進行了旋轉。例如,陣列 0,1,2,4,5,6,7 可能變為 4,5,6,7,0,1,2 搜尋乙個給定的目標值,如果陣列中存在這個目標值,則返回它的索引,否則返回 1 你可以假設陣列中不存在重複的元素。你的演算法時間複雜度必須是 o log n 級別。示例...
leetcode 搜尋旋轉排序陣列
假設按照公升序排序的陣列在預先未知的某個點上進行了旋轉。例如,陣列 0,1,2,4,5,6,7 可能變為 4,5,6,7,0,1,2 搜尋乙個給定的目標值,如果陣列中存在這個目標值,則返回它的索引,否則返回 1 你可以假設陣列中不存在重複的元素。你的演算法時間複雜度必須是 o log n 級別。示例...