搜索一個範圍

原題

  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).
  If the target is not found in the array, return [-1, -1].
  For example,
  Given [5, 7, 7, 8, 8, 10] and target value 8,
  return [3, 4].算法

題目大意

  給定一個排好序的數組,同時給定一個要查找的值 ,找出這個數在數組中的出如今起始和結束位置。
   算法的時間複雜度要求爲log(N)。
   若是沒有找到就返回[-1, -1]數組

解題思路

  (假定數組是遞增有序的)先用二分查找算法看數組中是否存在這個數,若是不存在就返回[-1,-1]
  若是存在就分別找這個數最後一次出來現的位置和最開始出現的位置。找最後出現的位置時,先從數組最後一個位置開始找,若是大於待找的值,就前近一個位置,還大於就前近2個,以2找指數數增長,若是小於就退回到原來位置的後一個進行查找,從新按1,2,四、、、這樣子的方式進行,直到找到爲止。對於找最早的元素也是同樣的。spa

代碼實現

算法實現類.net

public class Solution {
    public int[] searchRange(int[] A, int target) {

        if (A == null || A.length == 0) {
            return new int[]{-1, -1};
        }

        int lo = 0;
        int hi = A.length - 1;
        int mi = 0;
        // 查找數組中是否存在值爲target的元素
        while (lo <= hi) {
            mi = lo + (hi - lo) / 2;
            if (target < A[mi]) {
                hi = mi - 1;
            } else if (target > A[mi]) {
                lo = mi + 1;
            } else {
                break;
            }

        }

        if (A[mi] != target) {
            return new int[]{-1, -1};
        }

        lo = searchFirst(A, 0, mi, target);
        hi = searchLast(A, mi, A.length - 1, target);

        return new int[]{lo, hi};
    }

    /**
     * 找target最早出現的位置,查找的範圍是[lo, hi],A[hi]等於target,A爲有序數組
     *
     * @param A      待查找的數組
     * @param lo     查找的起始位置
     * @param hi     查找的結束位置
     * @param target 查找的值
     * @return target最早出現的位置
     */
    private int searchFirst(int[] A, int lo, int hi, int target) {

        int gap = 1;
        do {
            hi -= gap;
            if (hi < lo || A[hi] != target) {
                hi += gap;

                if (hi <= lo || A[hi - 1] != target) {
                    return hi;
                } else {
                    gap = 1;
                    hi--;
                }
            } else {// 在上一次的位置後退gap個依然相等
                gap *= 2;
            }
        } while (true);

    }

    /**
     * 找target最後出現的位置,查找的範圍是[lo, hi],A[lo]等於target,A爲有序數組
     *
     * @param A      待查找的數組
     * @param lo     查找的起始位置
     * @param hi     查找的結束位置
     * @param target 查找的值
     * @return target最後出現的位置
     */
    private int searchLast(int[] A, int lo, int hi, int target) {
        int gap = 1;
        do {
            lo += gap;
            if (lo > hi || A[lo] != target) {
                lo -= gap;

                if (lo >= hi || A[lo + 1] != target) {
                    return lo;
                } else {
                    gap = 1;
                    lo++;
                }
            } else {// 在上一次的位置前進gap個依然相等
                gap *= 2;
            }
        } while (true);
    }
}
相關文章
相關標籤/搜索