二分搜索练习

  二分搜索的的使用不一定是在有序数组中查找使用,只要是一次条件筛选之后能过滤掉一半数据之后都可以使用

#include<iostream>
#include<string>
#include<stack>//pop,top,push
#include<vector>
using namespace std;
class Solution
{
public:
    int getLessIndex(vector<int> arr)
    {
        if(arr.empty())//1.先判断是否为空
            return -1;
        if(arr.size()==1||arr[0]<arr[1])//2.判断数组开头
            return 0;
        if(arr[arr.size()-1]<arr[arr.size()-2])//3.判断数组结尾
            return arr.size()-1;

        int low=1,high=arr.size()-2,mid;
        while(low<=high)
        {
            mid=low+(high-low)/2;//为了防止low+high过大导致溢出
            if(arr[mid]>arr[mid-1])//从mid向左呈下降趋势,最小位置可能出现在mid左侧
                high=mid-1;
            else if(arr[mid]>arr[mid+1])//从mid向右呈下降趋势,最小位置可能出现在mid右侧
                low=mid+1;
            else//找到mid位置
                return mid;
        }
        return -1;
    }
};
int main()
{
    int a[30]={10,5,10,5,0,1,2,4,7,3,2,9,5,4,6,5,10,6,7,10,9,4,3,7,2,9,5,4,6,10};
    vector<int> arr(a,a+30);
    Solution s;
    cout<<s.getLessIndex(arr);
    return 0;
}

#include<iostream>
#include<string>
#include<bitset>//pop,top,push
#include<vector>
#include<cmath>
using namespace std;
class QuickPower
{
public://https://www.cnblogs.com/Knuth/archive/2009/09/04/1559949.html
    int getPower(int k, int N)
    {
        if(k==0)
            return 0;
        if(N==0)
            return 1;
        if(k>1000000007)
            k=k%1000000007;

        //arr数组中的每个值对应k的二进制bit中的每一位
        vector<long> arr;
        vector<int>  bit;
        //把k拆分为二进制操作
        long long  m=N,temp=k,res;
        while(m)
        {
            arr.push_back(temp);
            temp*=temp;
            if(temp>1000000007)
                temp=temp%1000000007;
            if(m%2)
                bit.push_back(1);
            else
                bit.push_back(0);
            m=m/2;
        }
        for(int i=0,res=1;i<bit.size();i++)
            if(bit[i])
            {
                res*=arr[i];
                if(res>1000000007)
                    res=res%1000000007;
            }
        return res%(1000000007);
    }
};
int main()
{
    QuickPower s;
    cout<<s.getPower(2,14876069);
    return 0;
}

  完全二叉树增加结点在树的最后一层从左到右依次添加,删除结点从右到左依次删除

  找根节点的右子树的最左子树出现的位置,是否和左子树中的最左子节点出现在同一层

struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :val(x), left(NULL), right(NULL) {}
};
class CountNodes {
public:
    int count(TreeNode* root)
    {
        if(!root)
            return 0;

        int Lengthofleft=DepthofCom_Bitree((*root).left);
        int Lengthofright=DepthofCom_Bitree((*root).right);
        //深度为h的二叉树最多有2^h-1个结点(h>=1),最少有h个结点
        if(Lengthofleft==Lengthofright)
            return pow(2.0,Lengthofleft)+count((*root).right);
        else
            return pow(2.0,Lengthofright)+count((*root).left);
    }
    int DepthofCom_Bitree(TreeNode *root)
    {
        if(!root)
            return 0;
        TreeNode *p=root;
        int len=0;
        while(p)
        {
            len++;
            p=(*p).left;
        }
        return len;
    }
};

#include<iostream>
#include<vector>
using namespace std;
class MinValue {
public:
    int getMin(vector<int> arr, int n)
    {
        if(arr.empty())
            exit(-1);
        if(n==1||arr[0]<arr[n-1])//整个数组是有序的
            return arr[0];

        int low=0,high=n-1,mid;
        while(low<high)
        {
            mid=low+(high-low)/2;
            if(arr[low]>arr[mid])//(升序数组)右半部分肯定移动到数组开头且最小值位于中间元素之前 6 5 1 2 3 4
                high=mid;
            else if(arr[mid]>arr[high])//最小值位于中间元素之后 4 5 6 1 2 3
                low=mid+1;
            else//arr[low]==arr[mid]==arr[high]  2 1 2 2 2 2
                break;
        }
        if(low==high)
            return arr[low];

        int min=arr[low];
        while(low<=high)
        {
            if(arr[low]<min)
                min=arr[low];
            low++;
        }
        return min;
    }
};
int main()
{
    int a[6]={4,5,6,1,2,3};
    vector<int> arr(a,a+6);
    MinValue s;
    cout<<s.getMin(arr,6);
    return 0;
}

#include<iostream>
#include<vector>
using namespace std;
class LeftMostAppearance 
{
public:
    int findPos(vector<int> arr, int n, int num) 
    {
        if(!n)
            return -1;
            
        int low=0,high=n-1,mid;
        int res=-1;
        while(low<=high)
        {
            mid=low+(high-low)/2;
            if(arr[mid]<num)
                low=mid+1;
            else if(arr[mid]>num)
                high=mid-1;
            else
            {
                res=mid;
                high=mid-1;
            }
        }
        return res;
    }
};
int main()
{
    int a[5]={1,2,3,3,4};
    vector<int> arr(a,a+5);
    LeftMostAppearance s;
    cout<<s.findPos(arr,5,3);
    return 0;
}

#include<iostream>
#include<vector>
using namespace std;
class Find {
public:
    int findPos(vector<int> arr, int n) 
    {
        if(arr.empty()||arr[0]>n-1||arr[n-1]<0)
            return -1;
            
        int res=-1;
        int low=0,high=n-1,mid=0;
        while(low<=high)
        {
            mid=low+(high-low)/2;
            if(arr[mid]<mid)//因为数组有序,所以左边的值都小于他的下标
                low=mid+1;
            else if(arr[mid]>mid)//右边得值肯定也都大于他的下标
                high=mid-1;
            else
            {
                res=mid;
                high=mid-1;
            }
        }
        return res;
    }
};
int main()
{
    int a[5]={-1,0,2,3};
    vector<int> arr(a,a+4);
    Find s;
    cout<<s.findPos(arr,4);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/tianzeng/p/11257167.html