美文网首页
二分法总结

二分法总结

作者: 丁不想被任何狗咬 | 来源:发表于2016-04-27 00:33 被阅读448次

待补充。

Leetcode上Binary Search题目(按frequency排序):
4 Median of Two Sorted Arrays
50 Pow(x, n)
153 Find Minimum in Rotated Sorted Array
33 Search in Rotated Sorted Array
69 Sqrt(x)
29 Divide Two Integers
162 Find Peak Element
278 First Bad Version
34 Search for a Range
35 Search Insert Position
74 Search a 2D Matrix
240 Search a 2D Matrix II
154 Find Minimum in Rotated Sorted Array II
81 Search in Rotated Sorted Array II
222 Count Complete Tree Nodes
287 Find the Duplicate Number
230 Kth Smallest Element in a BST
209 Minimum Size Subarray Sum
174 Dungeon Game
300 Longest Increasing Subsequence
275 H-Index II
167 Two Sum II - Input array is sorted
270 Closest Binary Search Tree Value
302 Smallest Rectangle Enclosing Black Pixels

本文题目目录:
1.search-a-2d-matrix
2.search-for-a-range
3.sqrtx
4.search-insert-position
5.find-minimum-in-rotated-sorted-array
6.find-minimum-in-rotated-sorted-array-ii
7.search-in-rotated-sorted-array
8.search-in-rotated-sorted-array-ii
9.find-peak-element

诀窍:
永远返回l法。初始的l和r取可能的最左(含)和最右(含)。永远让l处于可能为结果的那个位置(这样r自然也处于)。l = m的时候m = (l+r)/2+1, l = m+1的时候m = (l+r)/2。
如果发现不对的地方欢迎指正。

1.search a 2d matrix
l = mid+1而非mid,否则会陷入死循环。<target的时候,target只有可能在mid+1开始的地方,不可能为mid,所以l=mid+1。

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        if(matrix.size() == 0 || matrix[0].size() == 0) return false;
        int m = matrix.size();
        int n = matrix[0].size();
        int l = 0;
        int r = m * n - 1;
        int x,y;
        while(l < r) {
            int mid = l + (r - l) / 2;
            x = mid/n;
            y = mid%n;
            if(matrix[x][y] < target) {
                l = mid + 1;
            } else {
                r = mid;
            }
        }
        x = l/n;
        y = l%n;
        return matrix[x][y] == target;
    }
};

2.search for a range
找左侧:if(A[m]<target) 目标肯定在m+1往后(含)
找右侧:if(A[m]<=target) 目标肯定在m往后(含),l=m,所以m要+1,否则死循环

class Solution {
public:
    vector<int> searchRange(vector<int>& A, int target) {
        int n = A.size();
        int lres,rres;
        //find lres
        int l = 0;
        int r = n - 1;
        while(l < r) {
            int m = l + (r - l) / 2;
            if(A[m] < target) {
                l = m + 1;
            } else {
                r = m;
            }
        }
        lres = l;
        if(A[lres] != target) {
            return {-1, -1};
        }
        //find rres
        l = 0;
        r = n - 1;
        while(l < r) {
            int m = l + (r - l) / 2 + 1;
            if(A[m] <= target) {
                l = m;
            } else {
                r = m - 1;
            }
        }
        rres = l;
        return {lres, rres};
    }
};

3.sqrtx
类似上一题的find rres。
if(m <= x/m) 那么目标肯定在m往右(含),所以m要+1,l=m

class Solution {
public:
    int mySqrt(int x) {
        int l = 0;
        int r = x;
        while(l < r) {
            int m = l + (r - l) / 2 + 1;
            if(m <= x/m) {
                l = m;
            } else {
                r = m - 1;
            }
        }
        return l;
    }
};

4.search insert position
初始化的时候注意,最左可能为0,最右可能为n而不是n-1。
注意题意在nums[m] ==target时插入在m的位置。如果要插入到后面,就要让if(nums[m] < target)改为<=。

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int n = nums.size();
        int l = 0;
        int r = n;
        while(l < r) {
            int m = l + (r - l)/2;
            if(nums[m] < target) {
                l = m + 1;
            } else {
                r = m;
            }
        }
        return l;
    }
};

5.find minimum in rotated sorted array
类似上面,比较简单。

class Solution {
public:
    int findMin(vector<int>& nums) {
        int n = nums.size();
        int l = 0;
        int r = n - 1;
        while(l < r) {
            int m = l + (r - l) / 2;
            if(nums[m] < nums[r]) {
                r = m;
            } else {
                l = m + 1;
            }
        }
        return nums[l];
    }
};

6.find minimum in rotated sorted array ii

class Solution {
public:
    int findMin(vector<int>& nums) {
        int n = nums.size();
        if(n == 0) return -1;
        int l = 0;
        int r = nums.size() - 1;
        while(l < r) {
            int m = l + (r - l) / 2;
            if(nums[m] > nums[r]) {
                l = m + 1;
            } else if(nums[m] < nums[r]){
                r = m;
            } else {
                r--;
            }
        }
        return nums[l];
    }
};

改进else里面:

    if(nums[l] < nums[m])
        r = m - 1;
    else if(nums[l] > nums[m])
        r = m;
    else 
        r--;

7.search in rotated sorted array
思路1,直接做。思路2,先找到pivot,再做普通搜索(略)。
思路1:

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int l = 0;
        int r = nums.size() - 1;
        while(l < r) {
            int m = l + (r - l) / 2;
            if(nums[m] > nums[r]) {
                if(target >= nums[l] && target <= nums[m]) {
                    r = m;
                } else {
                    l = m + 1;
                }
            } else if(nums[m] < nums[r]) {
                if(target > nums[m] && target <= nums[r]) {
                    l = m + 1;
                } else {
                    r = m;
                }
            }
        }
        if(nums[l] == target) 
            return l;
        return -1;
    }
};

8.search in rotated sorted array ii
懒惰解法:
直接在上面的解法下面加一个else r--。内部加一个判断减少循环次数。

class Solution {
public:
    bool search(vector<int>& nums, int target) {
        int l = 0;
        int r = nums.size() - 1;
        while(l < r) {
            int m = l + (r - l) / 2;
            if(nums[m] == target) return true;
            if(nums[m] > nums[r]) {
                if(target >= nums[l] && target <= nums[m]) {
                    r = m;
                } else {
                    l = m + 1;
                }
            } else if(nums[m] < nums[r]) {
                if(target > nums[m] && target <= nums[r]) {
                    l = m + 1;
                } else {
                    r = m;
                }
            } else {
                r--;
            }
        }
        return nums[l] == target;
    }
};

9.Find Peak Element
返回随意一个的程序如下。如果让我找最左侧的那个呢?只能顺序找。

class Solution {
public:
    int findPeakElement(vector<int>& nums) {
        int l = 0;
        int r = nums.size() - 1;
        while(l < r) {
            int m = l + (r - l) / 2;
            if(nums[m] < nums[m+1]) {
                l = m + 1;
            } else {
                r = m;
            }
        }
        return l;
    }
};

相关文章

  • binary_search_special

    二分法总结参考:http://blog.csdn.net/ebowtang/article/details/507...

  • 二分法总结

    二分法总结 二分法貌似简单,实则很多细节,需要多加注意才能写对。 应用 1 在单调递增数组中确认是否有指定targ...

  • 中位数问题

    0X00 总结 4. Median of Two Sorted Arrays 二分法去做, 每次删除一个列表的元素...

  • 冒泡排序、选择排序和二分法查找

    冒泡排序 选择排序 二分法查找 概念 1.使用二分法好处: 可以加快寻找的效率。2.使用二分法特点: 二分法...

  • 二分法查找

    二分法基本查找 二分法遍历查找

  • 二分法查找

    二分法查找的前提是数组必须排序!!!二分法查找的前提是数组必须排序!!!二分法查找的前提是数组必须排序!!!二分法...

  • 二分法总结

    待补充。 Leetcode上Binary Search题目(按frequency排序):4 Median of T...

  • 手绘日常

    人物素描 今天重点讲二分法 二分法的重要性

  • python-递归-二分法

    二分法

  • 34 Search for a Range

    二分法

网友评论

      本文标题:二分法总结

      本文链接:https://www.haomeiwen.com/subject/moccrttx.html