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;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章