1095. 山脉数组中查找目标值(find-in-mountain-array)

1095. 山脉数组中查找目标值

题目大概就是说在一坐山里面找
在这里插入图片描述
示例 1:

输入:array = [1,2,3,4,5,3,1], target = 3
输出:2
解释:3 在数组中出现了两次,下标分别为 25,我们返回最小的下标 2

示例 2:

输入:array = [0,1,2,4,2,1], target = 3
输出:-1
解释:3 在数组中没有出现,返回 -1

提示:

3 <= mountain_arr.length() <= 10000
0 <= target <= 10^9
0 <= mountain_arr.get(index) <= 10^9

代码1

用三次二分搜索

public class Solution2 {
    public int findInMountainArray(int target, MountainArray mountainArr) {
        int len = mountainArr.length();
        //找到i
        int peakIndex = binarySearchTop(mountainArr, 0, len-1);
        //二分查找
        //在第一个有序数组中查找目标元素
        int res = binarySearch1(mountainArr, 0, peakIndex, target);
        if(res != -1) {
        	return res;
        }
        //在第二个有序数组中查找目标元素
        return binarySearch2(mountainArr, peakIndex + 1, len - 1, target);
    }

    private int binarySearchTop(MountainArray mountainArr, int left, int right) {
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (mountainArr.get(mid) < mountainArr.get(mid + 1)) {
            	//下一轮搜索区间[mid+1,right]
                left = mid + 1;
            } else {
            	//下一轮搜索区间[left,mid]
            	right = mid;
            }
        }
        //left == right
        return left;
    }
    
    //在[left...right] 查找target元素的下标
    private int binarySearch1(MountainArray mountainArr, int left, int right, int target) {
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (mountainArr.get(mid) < target) {
            	//下一轮搜索区间[mid+1,right]
                left = mid + 1;
            } else {
            	//下一轮搜索区间[left,mid]
            	right = mid;
            }
        }
        if(mountainArr.get(left) == target) {
        	return left;
        }
        return -1;
    }
    
    //在[left...right] 查找target元素的下标
    private int binarySearch2(MountainArray mountainArr, int left, int right, int target) {
        while (left < right) {
        	//加1变为上取整
            int mid = left + (right - left + 1) / 2;
            if (mountainArr.get(mid) < target) {
            	//下一轮搜索区间[left, mid - 1]
                right = mid  - 1;
            } else {
            	//下一轮搜索区间[left,right(mid)]
            	left = mid;
            }
        }
        if(mountainArr.get(left) == target) {
        	return left;
        }
        return -1;
    }

}

代码2

用三次二分搜索

/**
 * // This is MountainArray's API interface.
 * // You should not implement it, or speculate about its implementation
 * interface MountainArray {
 *     public int get(int index) {}
 *     public int length() {}
 * }
 */
 
class Solution {
    public int findInMountainArray(int target, MountainArray mountainArr) {
        int n = mountainArr.length();
        //找到i
        int i = binarySearchTop(mountainArr, 0, n);
        //二分查找
        int res1 = binarySearch1(mountainArr, 0, i + 1, target);
        int res2 = binarySearch2(mountainArr, i + 1, n, target);
        return res1 == -1 ? res2 : res1;
    }

    private int binarySearchTop(MountainArray mountainArr, int left, int right) {
        if (left < right) {
            int mid = left + (right - left) / 2;
            if (mid + 1 < mountainArr.length() && mountainArr.get(mid) < mountainArr.get(mid + 1)) {
                return binarySearchTop(mountainArr, mid + 1, right);
            } else {
                return binarySearchTop(mountainArr, left, mid);
            }
        }
        return left;
    }

    private int binarySearch1(MountainArray mountainArr, int left, int right, int target) {
        if (left < right) {
            int mid = left + (right - left) / 2;
            if (mountainArr.get(mid) == target) {
                return mid;
            } else if (mountainArr.get(mid) > target) {
                return binarySearch1(mountainArr, left, mid, target);
            } else {
                return binarySearch1(mountainArr, mid + 1, right, target);
            }
        }
        return -1;
    }

    private int binarySearch2(MountainArray mountainArr, int left, int right, int target) {
        if (left < right) {
            int mid = left + (right - left) / 2;
            if (mountainArr.get(mid) == target) {
                return mid;
            } else if (mountainArr.get(mid) > target) {
                return binarySearch2(mountainArr, mid + 1, right, target);
            } else {
                return binarySearch2(mountainArr, left, mid, target);
            }
        }
        return -1;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章