2016年小米校招笔试第二题(西安站)
2 现有一个数组是由有序数组经过n次循环移动后所得,请你用最快速度查找某个元素位置(如1234568,向右移动3次后为67812345)。
参考解法(Java版):
看题后第一直觉可能想去遍历数组,那么时间复杂度为o(n),不够高效。下面提供另一种参考方法。
package XiaoMi;
/********************************************************
* 解题思路:首先找到转折点,从转折点截断,原数组分成两个有序数组;
* 再利用二分查找对两段分别查找,最终返回查找结果。其中,对二分查
* 找算法做了一些改进,加了两个起始位、结束位两个参数,使用中更方便。
* *****************************************************/
import java.util.Arrays;
public class test14 {
/**
* @param args
*/
private final static String str = "67812345";
public static void main(String[] args) {
// TODO Auto-generated method stub
find(str, 3);
}
public static int find(String str, int in) {
// 将String输入转换为int数组
char[] chars = str.toCharArray();
int[] ints = new int[chars.length];
int i = 0;
for (char x : chars) {
//ints[i] = Integer.valueOf(x);
ints[i] =Integer.parseInt(x+""); //字符串转int型
//System.out.println(ints[i]);
++i;
}
// 查找排序转折点
int j = 0;
while (!(ints[j] >= ints[j + 1])) {
++j;
}
// 将数组从转折点截为两段有序数组,再运用二分查找
int loc =0;
if (in > ints[ints.length - 1]) { // 在左边
loc =binarySearch(ints, in, 0, j);
} else { // 在右边
loc =binarySearch(ints, in, j+1, ints.length - 1);
}
System.out.println(loc);
return 0;
}
// 改进二分查找
public static int binarySearch(int[] src, int des, int start, int end) {
int low = start;
int high = end;
while ((low <= high)){
int middle = low + ((high - low) >> 1);
if (des == src[middle]) {
return middle;
} else if (des < src[middle]) {
high = middle - 1;
} else {
low = middle + 1;
}
}
return -1;
}
}
运行结果:
5