LintCode 二分法查找, 搜索插入位置 和 二維矩陣

1. 二分查找

給定一個排序的整數數組(升序)和一個要查找的整數target,用O(logn)的時間查找到target第一次出現的下標(從0開始),如果target不存在於數組中,返回-1。
樣例
在數組 [1, 2, 3, 3, 4, 5, 10] 中二分查找3,返回2。
挑戰
如果數組中的整數個數超過了2^32,你的算法是否會出錯?

solution: 注意如果出現重複的數字時我們需要放回第一個出現的位置,因此在使用二分法查找時,我們需要添加一個while循環判斷前面是否有相同的數字.

class Solution {
public:
    /**
     * @param nums: The integer array.
     * @param target: Target number to find.
     * @return: The first position of target. Position starts from 0. 
     */
    int binarySearch(vector<int> &array, int target) {
        // write your code here
        int prev = 0, last = array.size()-1;
        while (prev <= last) {
            int mid = (prev + last) / 2;
            if (target > array[mid])
                prev = mid + 1;
            else if(target < array[mid])
                last = mid - 1;
            else {
                while (array[mid-1] == target) --mid;
                return mid;
            }
        }
        return -1;
    }
};

2. 搜索插入位置

給定一個排序數組和一個目標值,如果在數組中找到目標值則返回索引。如果沒有,返回到它將會被按順序插入的位置。
你可以假設在數組中無重複元素。
樣例
[1,3,5,6],5 → 2
[1,3,5,6],2 → 1
[1,3,5,6], 7 → 4
[1,3,5,6],0 → 0

solution:經典的二分查找算法

class Solution {
    /** 
     * param A : an integer sorted array
     * param target :  an integer to be inserted
     * return : an integer
     */
public:
    int searchInsert(vector<int> &A, int target) {
        // write your code here
        int n = A.size();
        int prev = 0, last = n - 1;

        while (prev <= last) {
            int mid = (prev + last) / 2;
            if(target > A[mid]) 
                prev = mid + 1;
            else if (target < A[mid])
                last = mid - 1;
            else 
                return mid;
        }
        return prev;
    }
};

3 搜索二維矩陣

寫出一個高效的算法來搜索 m × n矩陣中的值。
這個矩陣具有以下特性:
每行中的整數從左到右是排序的。
每行的第一個數大於上一行的最後一個整數。

樣例
考慮下列矩陣:
[
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]
給出 target = 3,返回 true
挑戰
O(log(n) + log(m)) 時間複雜度

solution: 這題是前面兩道題的綜合,首先找到target所在的行,然後在所在的列進行查找

code

class Solution {
public:
    /**
     * @param matrix, a list of lists of integers
     * @param target, an integer
     * @return a boolean, indicate whether matrix contains target
     */
    bool searchMatrix(vector<vector<int> > &matrix, int target) {
        // write your code here
        if (matrix.size() == 0)
            return false;
        int m = matrix.size()-1;
        int row = 0, last = m, mid;
        //首先找到元素所在的行
        while (row <= last) {
            mid = (row + last) / 2;
            if (matrix[mid][0] < target) 
                row = mid + 1;
            else if (matrix[mid][0] > target)
                last = mid - 1;
            else 
                return true;
        }
        row -= 1;   //注意此處
        last = matrix[row].size() - 1;
        int col = 0;
        while (col <= last) {
            mid = (col + last) / 2;
            if (matrix[row][mid] < target)
                col = mid + 1;
            else if (matrix[row][mid] > target)
                last = mid - 1;
            else 
                return true;
        }
        return false;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章