二进制搜索可以在旋转排序列表中查找旋转点 [英] Binary search to find the rotation point in a rotated sorted list
问题描述
我有一个排序的列表,它被旋转,并希望在该列表上进行二进制搜索以找到最小元素。
I have a sorted list which is rotated and would like to do a binary search on that list to find the minimum element.
假设初始列表是{1 ,2,3,4,5,6,7,8}
旋转列表可以像{5,6,7,8,1,2,3,4}
Lets suppose initial list is {1,2,3,4,5,6,7,8} rotated list can be like {5,6,7,8,1,2,3,4}
正常二进制搜索在这种情况下不起作用。任何想法如何做到这一点。
Normal binary search doesn't work in this case. Any idea how to do this.
- 修改
我有另一个条件。如果列表没有排序怎么办?
I have one another condition. What if the list is not sorted??
推荐答案
二进制搜索算法的一个修改就是你需要的;以下是完整可运行Java的解决方案(请参阅 Serg的答案用于Delphi实现,而 tkr的答案,用于视觉解释算法)。
A slight modification on the binary search algorithm is all you need; here's the solution in complete runnable Java (see Serg's answer for Delphi implementation, and tkr's answer for visual explanation of the algorithm).
import java.util.*;
public class BinarySearch {
static int findMinimum(Integer[] arr) {
int low = 0;
int high = arr.length - 1;
while (arr[low] > arr[high]) {
int mid = (low + high) >>> 1;
if (arr[mid] > arr[high]) {
low = mid + 1;
} else {
high = mid;
}
}
return low;
}
public static void main(String[] args) {
Integer[] arr = { 1, 2, 3, 4, 5, 6, 7 };
// must be in sorted order, allowing rotation, and contain no duplicates
for (int i = 0; i < arr.length; i++) {
System.out.print(Arrays.toString(arr));
int minIndex = findMinimum(arr);
System.out.println(" Min is " + arr[minIndex] + " at " + minIndex);
Collections.rotate(Arrays.asList(arr), 1);
}
}
}
打印:
[1, 2, 3, 4, 5, 6, 7] Min is 1 at 0
[7, 1, 2, 3, 4, 5, 6] Min is 1 at 1
[6, 7, 1, 2, 3, 4, 5] Min is 1 at 2
[5, 6, 7, 1, 2, 3, 4] Min is 1 at 3
[4, 5, 6, 7, 1, 2, 3] Min is 1 at 4
[3, 4, 5, 6, 7, 1, 2] Min is 1 at 5
[2, 3, 4, 5, 6, 7, 1] Min is 1 at 6
另请参阅
- Java Collections.rotate()与数组不起作用$
- 解释为什么
Integer []
而不是int []
- Java Collections.rotate() with an array doesn’t work
- Explains why
Integer[]
instead ofint[]
- 解释为什么
>>> 1
而不是/ 2
- Explains why
>>> 1
instead of/ 2
请注意,重复项不可能在
O(log N)
。考虑以下位数组,它由许多1
和一个0
组成:Note that duplicates makes it impossible to do this in
O(log N)
. Consider the following bit array consisting of many1
, and one0
:(sorted) 01111111111111111111111111111111111111111111111111111111111111111 ^ (rotated) 11111111111111111111111111111111111111111111101111111111111111111 ^ (rotated) 11111111111111101111111111111111111111111111111111111111111111111 ^
可以在
N
中旋转,并将0
在O(log N)
是不可能的,因为没有办法告诉它是否在中间的左侧或右侧。This array can be rotated in
N
ways, and locating the0
inO(log N)
is impossible, since there's no way to tell if it's in the left or right side of the "middle".
我有另一个条件。如果列表没有排序,该怎么办?
I have one another condition. What if the list is not sorted??
然后,除非你想先排序,然后从那里进行排序进行线性搜索以找到最小值。
Then, unless you want to sort it first and proceed from there, you'll have to do a linear search to find the minimum.
- <一个href =http://en.wikipedia.org/wiki/Selection_algorithm#Linear_minimum.2Fmaximum_algorithms =noreferrer>维基百科|选择算法|线性最小/最大算法
- Wikipedia | Selection algorithm | Linear minimum/maximum algorithms
这篇关于二进制搜索可以在旋转排序列表中查找旋转点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
- Explains why
See also
- 解释为什么