zoukankan      html  css  js  c++  java
  • 二分搜索练习

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

    #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;
    }
  • 相关阅读:
    USACO 2019 January Contest Platinum T2: Exercise Route
    USACO 2016 December Contest Gold T3: Lasers and Mirrors
    USACO 2016 December Contest Gold T2: Cow Checklist
    USACO 2016 December Contest Gold T1: Moocast
    USACO 2016 US Open Contest Gold T3: 248
    洛谷p5369[PKUSC2018]最大前缀和
    洛谷p5465 [PKUSC2018]星际穿越
    洛谷p3778[APIO2017]商旅
    NOIP2018提高组题解
    NOIP2017提高组题解
  • 原文地址:https://www.cnblogs.com/tianzeng/p/11257167.html
Copyright © 2011-2022 走看看