二分搜索——从LeetCode题海中总结常见套路

目录

LeetCode34.在排序数组中查找元素的第一个和最后一个位置

LeetCode153.寻找旋转排序数组中的最小值

LeetCode154.寻找旋转排序数组中的最小值II

瞎暴力:面试这么写稳稳挂

二分:注意重复元素的处理情况

LeetCode852.山脉数组的峰顶索引

LeetCode230.二叉搜索树中第K小的元素

LeetCode671.二叉树中第二小的节点

LeetCode1237.找出给定方程的正整数解

瞎暴力

剪枝优化

思考二分:

LeetCode287.寻找重复数

哈希表

木桶法

LeetCode面试题08.03魔术索引

瞎暴力

利用有序数组性质

LeetCode面试题53-II.0~n-1中缺失的数字


LeetCode34.在排序数组中查找元素的第一个和最后一个位置

在这道题中用左右指针和二分查找的时间一样,但时间复杂度不一样

二分搜索——从LeetCode题海中总结常见套路_第1张图片

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

LeetCode153.寻找旋转排序数组中的最小值

超级经典的二分,这里没有重复的数组,所以处理起来会比下一题简单很多!

二分搜索——从LeetCode题海中总结常见套路_第2张图片

class Solution {
public:
    int findMin(vector& nums) {
        int left = 0;
        int right = nums.size()-1;
        while(leftnums[right])
                left = mid + 1;
            else
                right = mid;
        }
        return nums[left];
    }
};

LeetCode154.寻找旋转排序数组中的最小值II

吐槽一句:这里是《剑指offer》上面的原题,但是剑指那本书对于这道题的思路讲解的非常棒,但是代码写的太垃圾了的,可读性很低!

二分搜索——从LeetCode题海中总结常见套路_第3张图片

瞎暴力:面试这么写稳稳挂

class Solution {
public:
    int minArray(vector& numbers) {
        for(int i = 1; i

二分:注意重复元素的处理情况

想一下,如果mid到right全部都是重复元素,没有最后一个else里的right--时候,是不是会出现死循环的情况?所以这里的这个点特别要注意!

class Solution {
public:
    int findMin(vector& nums) {
        int left = 0;
        int right = nums.size()-1;
        while(leftnums[right])
                left = mid+1;
            else if(nums[mid]

LeetCode852.山脉数组的峰顶索引

二分搜索——从LeetCode题海中总结常见套路_第4张图片

笨方法当然是找到最大值的下标然后垫底

class Solution {
public:
    int peakIndexInMountainArray(vector& A) {
        vector a(A.begin(),A.end());
        sort(a.begin(),a.end());
        int b = a[a.size()-1];//找到最大值
        for(int i = 0;i

忽然发现不同二分,直接从左向右遍历,遇到右比作左大的情况就找到了

class Solution {
public:
    int peakIndexInMountainArray(vector& A) {
        for(int i=0;iA[i+1])//山峰出现
                return i;
        }
        return 0;
    }
};

LeetCode230.二叉搜索树中第K小的元素

一分钟搞了个中序遍历AC,还是没有用到二分,很失望

二分搜索——从LeetCode题海中总结常见套路_第5张图片

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
private:
    vector v;
public:
    int kthSmallest(TreeNode* root, int k) {
        InOrderTraver(root,k);
        return v[k-1];
    }
    void InOrderTraver(TreeNode* root,int k){
        if(root==NULL)
            return;
        InOrderTraver(root->left,k);
        v.push_back(root->val);
        if(v.size()==k)//到第K个就停下
            return;
        InOrderTraver(root->right,k);
    }
};

LeetCode671.二叉树中第二小的节点

又没用二分,遍历大法好,失望……

二分搜索——从LeetCode题海中总结常见套路_第6张图片

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
private:
    set s;
public:
    int findSecondMinimumValue(TreeNode* root) {
        PreOrderTraver(root);
        if(s.size()<2)
            return -1;
        set::iterator it = s.begin();
        it++;
        return *it;
    }
    void PreOrderTraver(TreeNode* root){
        if(root==NULL)
            return;
        s.insert(root->val);
        PreOrderTraver(root->left);
        PreOrderTraver(root->right);
    }
};

LeetCode1237.找出给定方程的正整数解

二分搜索——从LeetCode题海中总结常见套路_第7张图片

瞎暴力

一开始不很清楚,看一眼提示,瞬间用暴力AC

没有利用递增的性质,面试这么说就挂了

/*
 * // This is the custom function interface.
 * // You should not implement it, or speculate about its implementation
 * class CustomFunction {
 * public:
 *     // Returns f(x, y) for any given positive integers x and y.
 *     // Note that f(x, y) is increasing with respect to both x and y.
 *     // i.e. f(x, y) < f(x + 1, y), f(x, y) < f(x, y + 1)
 *     int f(int x, int y);
 * };
 */

class Solution {
public:
    vector> findSolution(CustomFunction& customfunction, int z) {
        vector> vv;
        for(int i=1;i<=1000;i++){
            for(int j=1;j<=1000;j++){
                vector v;
                if(customfunction.f(i,j)==z){
                    v.push_back(i);
                    v.push_back(j);
                    vv.push_back(v);
                }
            }
        }
        return vv;
    }
};

剪枝优化

/*
 * // This is the custom function interface.
 * // You should not implement it, or speculate about its implementation
 * class CustomFunction {
 * public:
 *     // Returns f(x, y) for any given positive integers x and y.
 *     // Note that f(x, y) is increasing with respect to both x and y.
 *     // i.e. f(x, y) < f(x + 1, y), f(x, y) < f(x, y + 1)
 *     int f(int x, int y);
 * };
 */

class Solution {
public:
    vector> findSolution(CustomFunction& customfunction, int z) {
        vector> vv;
        for(int i=1;i<=1000;i++){
            for(int j=1;j<=1000;j++){
                vector v;
                if(customfunction.f(i,j)==z){
                    v.push_back(i);
                    v.push_back(j);
                    vv.push_back(v);
                }else if(customfunction.f(i,j)>z){//利用递增的性质将不可能的解法剔除,属于剪枝
                    break;
                }
            }
        }
        return vv;
    }
};

思考二分:

因为是递增的,所有对每个x取值,最多只能由一个y值,再利用递增的性质,二分查找;

反过来,对于每个y取值,最多只能由一个x值满足;

所以,单独二分只能利用一个变量递增的性质,还是会有浪费啊!

最好的是双指针二分,这样一点时间浪费都没有,但是我懒啊,不做了哈哈哈下一题

还是贴一个别人的吧,其实思路构思出来的话一分钟也能A

vector> findSolution(CustomFunction& customfunction, int z) {
    vector> res = {};
    int x =1; int y = 1000;
    while(x<=1000 && y>=1 ){
        if(customfunction.f(x,y) == z) {
            res.push_back({x,y});
            ++x;--y;
        }
        else if(customfunction.f(x,y)

LeetCode287.寻找重复数

二分搜索——从LeetCode题海中总结常见套路_第8张图片

哈希表

class Solution {
public:
    int findDuplicate(vector& nums) {
        map m;
        for(int i=0;i=2)
                return nums[i];
        }
        return 0;
    }
};

木桶法

因为我们提前知道木桶下标值的范围,所以用木桶法代替哈希表法可以更为方便

class Solution {
public:
    int findDuplicate(vector& nums) {
        int a[nums.size()+1];
        for(int i=1;i<=nums.size();i++)
            a[i]= 0;
        for(int i=0;i=2)
                return nums[i];
        }
        return 0;
    }
};

 

LeetCode面试题08.03魔术索引

二分搜索——从LeetCode题海中总结常见套路_第9张图片

瞎暴力

遇事不决量子力学,啥也不会直接暴力

根本就没有利用有序数组的性质,面试gg

class Solution {
public:
    int findMagicIndex(vector& nums) {
        int min = (1<<21);
        for(int i=0;i

利用有序数组性质

直接从头开始找最小,二分太浪费了吧?

class Solution {
public:
    int findMagicIndex(vector& nums) {
        for(int i=0;i

LeetCode面试题53-II.0~n-1中缺失的数字

二分搜索——从LeetCode题海中总结常见套路_第10张图片

class Solution {
public:
    int missingNumber(vector& nums) {
        int left = 0;
        int right = nums.size()-1;
        while(left<=right){
            int mid = (left+right)/2;
            if(mid == nums[mid])    //以中间的数组下标是否对应数组值为判断标准
                left = mid+1;
            else
                right = mid-1;
        }
        return left;
    }
};

 

你可能感兴趣的:(LeetCode,算法笔记—数学,LeetCode经典)