数组中部分有序数据查找某个数

今天一哥们去美团面试碰到个面试题目,跟我吐槽没做好,题目大概思想是一个有序的数组,把前面有序的一部分放到数组后面,是整个数组变成部分有序,也就是先递增,中断,然后再递增:

具体如下:
 本来是 2  5  9  11  12  15  16 ,现在把最后的几个放在前面,
就出现 12  15  16  2  5  9  11  这样的了
判断某个数字在不在数组中 ,不接受复杂度高于O(N)的查找,



晚上用java代码实现了下,基本思想是先利用二分查找找到最大数的位置,

然后再用二分查找查找找出target的位置,找到返回目标值,没找到返回-1

算法复杂度为O(logn)



package com.iclick.aerospike;

public class App {

	public static void main(String[] args) {
		int[] arr = { 11, 12, 15, 16, 18, 19, 33, 40, 1, 2, 5, 6, 8, 10 };
		System.out.println(search(arr, 33));

	}

	public static int search(int[] arr, int target) {
		int result = -1;
		int maxPosition = searchMaxPosition(arr);
		if (target > arr[maxPosition] || target < arr[maxPosition + 1]) {
			result = -1;
		} else if (target <= arr[maxPosition] && target >= arr[0]) {
			result = binearSearch(arr, 0, maxPosition, target);
		} else if (target >= arr[maxPosition + 1]
				&& target <= arr[arr.length - 1]) {
			result = binearSearch(arr, maxPosition + 1, arr.length - 1, target);
		}

		return result;
	}

	public static int binearSearch(int arr[], int start, int end, int target) {
		int middle = 0;
		while (start <= end) {
			middle = (start + end) / 2;
			if (arr[middle] == target) {
				return target;
			} else if (arr[middle] > target) {
				end = middle - 1;

			} else if (arr[middle] < target) {
				start = middle + 1;

			}
		}

		return -1;
	}

	public static int searchMaxPosition(int[] arr) {
		int start = 0;
		int end = arr.length - 1;
		int middle = 0;
		while (true) {
			middle = (start + end) / 2;
			if (arr[middle] > arr[start]) {
				start = middle;
			} else if (arr[middle] < arr[end]) {
				end = middle;
			} else {
				return start;
			}
		}
	}

	/*
	 * public static int searchMaxPosition(int[] arr) { int start = 0; int end =
	 * arr.length - 1; int middle = 0; while (start < end) { middle = (start +
	 * end) / 2;
	 * 
	 * if (arr[middle] > arr[middle + 1] && arr[middle] > arr[middle - 1]) {
	 * //这样的数一定存在,就是数组中最大的数 break; } else if (arr[middle] > arr[middle - 1] &&
	 * arr[middle] < arr[arr.length - 1]) {
	 * 
	 * end = middle;
	 * 
	 * } else if (arr[middle] > arr[middle - 1] && arr[middle] > arr[arr.length
	 * - 1]) { start = middle;
	 * 
	 * } else { end = middle; } } return middle;
	 * 
	 * }
	 */

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值