先熟悉一下二分查找(java代码实现):
package suanfa;
public class Search {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6};
int key = 6;
int index = binarySearch(arr,0,arr.length-1,key);
System.out.println(index);
}
/**递归算法
* 二分查找算法
* @param arr
* @param i
* @param j
* @param key
* @return
*/
public static int binarySearch(int[] arr,int i ,int j ,int key){
if(i>j || arr[j]< key || arr[i] >key ) return -1;
int mid = (i +j ) /2;
if(arr[mid] > key){//在左边
return binarySearch(arr,i,mid-1,key);
}else if(arr[mid] < key){//在右边
i = mid+1;
binarySearch(arr,mid+1,j,key);
}else{
return mid;
}
}
/**非递归算法:循环
* 二分查找算法
*/
public static int binarySearch(int[] arr,int i ,int j ,int key){
if(i>j || arr[j]< key || arr[i] >key ) return -1;
while(i<j){
int mid = (i +j ) /2;
if(arr[mid]>key){
j = mid-1;
}else if(arr[mid] < key){
i = mid+1
}else{
return mid;
}
}
return -1;
}
}
常见TT面试题:
在循环左移后的有序且不重复的数组中搜索目标值x
例如:数组a = [1, 2, 3, 4, 5]是有序的,循环左移后可能得到a = [4, 5, 1, 2, 3],在循环左移n(n未知)次后的数组a中搜索是否存在目标值x,如果存在返回下标,不存在返回-1。
要求性能尽可能高。
输入描述
循环后的数组为 [4, 5, 6, 7, 8, 9, 1, 2, 3],输入目标值x=4
输出描述
找到目标值,打印下标值,例如x=4时,输出0;
示例1
输入 4
输出 0
算法方法:
package suanfa;
import java.util.Scanner;
public class RecircleSearch {
public static void main(String[] args) {
int[] arr = { 4, 5, 6, 7, 8, 9, 1, 2, 3 };
Scanner scanner = new Scanner(System.in);
int key = scanner.nextInt();
int n = 3;
int resultIndex = recircleMove(arr, n, key);
System.out.println(resultIndex);
}
public static int recircleMove(int[] arr, int n, int key) {
int size = arr.length;
if (arr[0] == key) {
return 0;
}
int middleIndex = n > 5 ? n % size : size - n;
if (middleIndex == 0) {
return binarySearch(arr, 0, size - 1, key);
}
if (arr[0] > key)
return binarySearch(arr, middleIndex, size - 1, key);
if (arr[0] < key)
return binarySearch(arr, 0, middleIndex - 1, key);
return -1;
}
public static int binarySearch(int[] arr, int i, int j, int key) {
int mid = (i + j) / 2;
if (arr[mid] == key)
return mid;
if (i == j && arr[mid] != key) {
return -1;
}
if (arr[mid] > key) {// 在左边
j = mid - 1;
}
if (arr[mid] < key) {// 在右边
i = mid + 1;
}
return binarySearch(arr, i, j, key);
}
}
当输入:4时候,输出查找元素的下标位置0;
当输入100时候,没有找到元素则下标返回-1;
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/788a40754b66d2bef2a6978bd5591078.png)
思考:在做该题中心情紧张一时不知道该从哪里下手,后来在msg的提醒下使用二分查找,才在后来做出来该题。汗颜!!!问题原因:
1.有序数组的查找问题,使用二分查找来解决。时间复杂度为O(log2n)
2.对于移动的数组元素,当移动n次时,分为两个有序数组,其中第二个有序数组下标可以通过移动次数求出middleIndex = n > 5 ? n % size : size - n; (其中n为移动次数,size数组长度),则middleIndex 为第二个数组的开始下标;
3.我使用的是二分查找的递归方法,考虑使用非递归方法实现。