二分搜索

查找搜索在我们平时的开发中,用到的还是挺多的,所以对于一般的搜索算法,我们也是需要了解一下的。


问题:查找指定元素的位置

    public int binarySearch(int[] array, int target) { // O(Log2N) O(1)
        if (array == null || array.length == 0) return -1;
        int left = 0;
        int right = array.length - 1;
        while (left <= right) {
            int mid = left + (right - left) / 2; // integer may out of bound
            if (array[mid] < target) {
                left = mid + 1;
            } else if (array[mid] > target) {
                right = mid - 1;
            } else {
                return mid;
            }
        }
        return -1;
    }

上面这段代码就是二分查找算法,终结条件就是 left > right,这是二分查找的核心。
时间复杂度 O(log2N)
空间复杂度 O(1)


问题:查找第一个出现的元素

描述:给定一个目标整数 T 和一个按升序排序的整数数组,如果找到整数 T 第一次出现的位置,就返回该位置索引,否则,返回-1。

例子:
A = {1,2,3} T = 2,return 1
A = {1,2,3} T = 4,return -1
A = {1,2,2,2,2,3} T = 2,return 1

    public int findFirst(int[] array, int target) { // O(Log2N) O(1)
        if (array == null || array.length == 0) return -1;
        int left = 0;
        int right = array.length - 1;
        while (left < right - 1) {
            int mid = left + (right - left) / 2;
            if (array[mid] < target) {
                left = mid;
            } else if (array[mid] >= target) {
                right = mid;
            }
        }

        // post processing
        if (array[left] == target) return left;
        if (array[right] == target) return right;

        return -1;
    }

时间复杂度 O(log2N)
空间复杂度 O(1)


问题:查找指定元素的位置

描述:给定一个目标整数 T 和一个按升序排序的整数数组,找出 T 在数组中最接近 T 的元素的索引。

例子:
A = {1,2,3} T = 2,return 1
A = {1,4,6} T = 3,return 1
A = {1,4,6} T = 5,return 1 or 2
A = {1,3,3,4} T = 2,return 0 or 1 or 2

    public int findClosest(int[] array, int target) { // O(Log2N) O(1)
        if (array == null || array.length == 0) return -1;
        int left = 0;
        int right = array.length - 1;
        while (left < right - 1) {
            int mid = left + (right - left) / 2;
            if (array[mid] == target) {
                return mid;
            } else if (array[mid] > target) {
                right = mid;
            } else {
                left = mid;
            }
        }
        // post processing
        if ( Math.abs( target - array[left] ) <= Math.abs( target - array[right] ) ) {
            return left;
        } else {
            return right;
        }
    }

问题:查找指定元素的位置

/**
 * array: m * n
 * time: log(number of elements) -log(m * n)
 * space:O(1)
 */
public class SearchMatrix {

    public static void main(String[] args) {
        int[][] matrix = {
                {1, 2, 3},
                {4, 5, 6},
                {7, 8, 9},
                {10, 11, 12}
        };
        int[] index = new SearchMatrix().searchMatrix(matrix, 7);
        System.out.println("index:" + index[0] + " " + index[1]);
    }

    public int[] searchMatrix(int[][] matrix, int target) { // O(Log2 M x N) O(1)
        int[] res = {-1, -1};
        int num_row = matrix.length;
        int num_col = matrix[0].length;
        int left = 0;
        int right = num_row * num_col - 1;
        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (target == matrix[mid / num_col][mid % num_col]) {
                res[0] = mid / num_col;
                res[1] = mid % num_col;
                return res;
            } else if (matrix[mid / num_col][mid % num_col] > target) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        return res;
    }

}

你可能感兴趣的:(数据结构与算法)