【Leetcode】Search for a Range

来源:互联网 发布:windows解压mac压缩包 编辑:程序博客网 时间:2024/06/03 16:22

Given a sorted array of integers, find the starting and ending position of a given target value. Your algorithm's runtime complexity must be in the order of O(log n).

这道题让寻找一个搜索范围,基本思路还是和二分搜索的模型一样,直接上代码,再逐块解析

public int[] searchRange(int[] A, int target) {int[] result = new int[2];result[0] = -1;result[1] = -1;if (A == null || A.length == 0)return result;int left = 0;int right = A.length - 1;int middle = 0;while (left <= right) {middle = (left + right) / 2;if (A[middle] == target) {result[0] = middle;result[1] = middle;break;}if (A[middle] < target)left = middle + 1;elseright = middle - 1;}if (A[middle] != target)return result;int newLeft = 0;int newRight = middle - 1;while (newLeft <= newRight) {int newMiddle = (newLeft + newRight) / 2;if (A[newMiddle] == target)newRight = newMiddle - 1;elsenewLeft = newMiddle + 1;}result[0] = newLeft;newLeft = middle + 1;newRight = A.length - 1;while (newLeft <= newRight) {int newMiddle = (newLeft + newRight) / 2;if (A[newMiddle] == target)newLeft = newMiddle + 1;elsenewRight = newMiddle - 1;}result[1] = newRight;return result;}

首先第一步是和二分搜索的思路完全一样,直接找一个可行解,如果没找到,返回【-1,-1】。

int left = 0;int right = A.length - 1;int middle = 0;while (left <= right) {middle = (left + right) / 2;if (A[middle] == target) {result[0] = middle;result[1] = middle;break;}if (A[middle] < target)left = middle + 1;elseright = middle - 1;}if (A[middle] != target)return result;

然后扩展左界,思路是让左指针指向最左边的一个满足目标值的位置,范围是从0~middle-1

如果A[newMiddle]==target, 收敛右指针

否则收敛左指针。

int newLeft = 0;int newRight = middle - 1;while (newLeft <= newRight) {int newMiddle = (newLeft + newRight) / 2;if (A[newMiddle] == target)newRight = newMiddle - 1;elsenewLeft = newMiddle + 1;}result[0] = newLeft;

最后扩展右界,思路是让右指针指向最右边的一个满足目标值的位置,范围是从middle+1~A.length-1

如果A[newMiddle]==target, 收敛左指针

否则收敛右指针。

newLeft = middle + 1;newRight = A.length - 1;while (newLeft <= newRight) {int newMiddle = (newLeft + newRight) / 2;if (A[newMiddle] == target)newLeft = newMiddle + 1;elsenewRight = newMiddle - 1;}result[1] = newRight;return result;}

这道题用循环,代码比较多,如果用递归,代码会简单很多

public int[] searchRange(int[] A, int target) {int[] result = new int[2];result[0] = -1;result[1] = -1;if (A == null || A.length == 0)return result;int index = binarySearch(A, 0, A.length - 1, target);if (index != -1) {int left = index;int right = index;result[0] = left;result[1] = right;while ((left = binarySearch(A, 0, left - 1, target)) != -1)result[0] = left;while ((right = binarySearch(A, right + 1, A.length - 1, target)) != -1)result[1] = right;}return result;}public int binarySearch(int[] A, int left, int right, int target) {if (left > right)return -1;int middle = (left + right) / 2;if (A[middle] == target)return middle;if (A[middle] > target)return binarySearch(A, left, middle - 1, target);elsereturn binarySearch(A, middle + 1, right, target);}

还有一种更牛的解法是寻找目标值的-0.5和+0.5.然后a指向-0.5, b指向0.5,然后返回【a, b-1】就可以了

比如[5,7,7,8,8,10] 如果要找8,直接搜7.5和8.5 这样能找到3和5,然后返回3和4就可以了

代码如下

public int[] searchRange(int[] A, int target) {int[] result = new int[2];result[0] = -1;result[1] = -1;if (A == null || A.length == 0)return result;double T1 = target - 0.5;double T2 = target + 0.5;result[0] = binarySearch(A, 0, A.length - 1, T1);result[1] = binarySearch(A, 0, A.length - 1, T2) - 1;if (result[0] > result[1]) {int[] err = { -1, -1 };return err;}return result;}public int binarySearch(int[] A, int left, int right, double target) {if (left > right)return left;int middle = (left + right) / 2;if (A[middle] > target)return binarySearch(A, left, middle - 1, target);elsereturn binarySearch(A, middle + 1, right, target);}


0 0
原创粉丝点击