首页 > 其他分享 >LeeCode例题——二分查找

LeeCode例题——二分查找

时间:2023-03-12 18:35:12浏览次数:25  
标签:二分 return target nums int LeeCode left 例题 out

1.二分查找:(面对一个升序排列的数组)

class Soulution {
public:
  int search(vector<int>& nums, int target) {//函数名(数组,变量)
  int left = 0, right = nums.size() - 1;//声明变量left定义为数组的左边界,变量right定义为数组的右边界。
  while(left <= right){
    int mid = (right - left)/2 + left;//取数组的中间位置
    int num = muns[mid];//取数组的中间位置的元素
    if (num == target){//当寻找的变量等于数组中间位置的元素时,返回为中间未知的下标
        return mid;
    }else if (target < num){//当寻找的变量小于mid时,将右边界定义为mid-1,下次while循环计算mid的位置时,mid代表左边界的中间,从数组的左边开始寻找
        right = mid -1
    }else {//当寻找的变量大于mid时,将左边界定义为mid+1,下次while循环计算mid的位置时,mid代表右边界的中间,从数组的右边开始寻找
        left = mid +1
    }
  }
  return -1;//查找无果则返回-1
};

本算法耗时32ms,LeeCode上有更快的算法,最离谱的是有4ms的算法。
28ms:(可能是我才疏学浅,没看出这个和32ms的有什么区别)

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

24ms:
下面是我对这个算法快于32ms算法的理解:
1.这个算法在第一个if和第二个if中先处理了基准情况,按照书上的说法,应该是这样理解的吧。
2.在第三个if中加入break提前终止。

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int m, start = 0, end = nums.size()-1;//和第一个算法一样,先定义左边界和右边界
        int flag = -1;
        int tmp = 0;
        while(start <= end){//当左边界小于右边界时
            m = (start + end ) / 2;//m为数组的中间位置
            tmp = nums[m];//tmp为数组中m位置上的数字
            if(start == end){//当左边界等于右边界时,即数组中只有一个数字
                if(target==nums[m]){//如果查找到变量target则返回m
                    return m;
                }else{
                    return -1;//没有则返回-1
                }
            }
            if (tmp == target){//当tmp==target时返回flag,且结束循环
                flag = m;
                break;
            }else if (tmp > target){//接下来和32ms算法同理
                end = m;
            }
            else {
                start = m+1;
            }
        }
        return flag;
    }
};

20ms:
1.相比于32ms的算法,这个算法只声明了两个变量,第三个变量num用nums[num]代替,其他的原谅我才疏学浅,看不出来。

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

            return -1;
    }
};

16ms:(好像和那个24ms的算法一样啊)

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

12ms:

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int n = nums.size();//初始化变量n为数组的长度
        if(n == 0 ) return -1;//这里优先处理了基准情况,当数组长度为0时直接返回-1
        int l = 0, r = n-1, mid ;//初始化变量为l,r为数组的左边界和右边界,声明变量mid为整型
        while(l <= r){//和32ms算法一样
            mid = (r+l)/2;
            if(nums[mid] == target) return mid;
            else if(nums[mid] < target) l = mid+1;
            else if(nums[mid] > target) r = mid-1;
        }
        return -1;
    }
};

8ms:
降维打击了。

int init = [] {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    ofstream out("user.out");
    for (string s; getline(cin, s); out << '\n') {
        string t;
        getline(cin, t);
        int tar = stoi(t);
        for (int i = 0, _i = 1, _n = s.length(); _i < _n; ++i, ++_i) {
            bool _neg = false;
            if (s[_i] == '-') ++_i, _neg = true;
            int v = s[_i++] & 15;
            while ((s[_i] & 15) < 10) v = v * 10 + (s[_i++] & 15);
            if (_neg) v = -v;

            if (v == tar) {
                out << i;
                goto next;
            }
            if (v > tar) break;
        }
        out << -1;
        next:;
    }
    out.flush();
    exit(0);
    return 0;
}();

class Solution {
public:
    int search(vector<int>, int) { return 0; }
};

4ms:

int init = [] {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    ofstream out("user.out");
    for (string s; getline(cin, s); out << '\n') {
        string t;
        getline(cin, t);
        int tar = stoi(t);
        for (int i = 0, _i = 1, _n = s.length(); _i < _n; ++i, ++_i) {
            bool _neg = false;
            if (s[_i] == '-') ++_i, _neg = true;
            int v = s[_i++] & 15;
            while ((s[_i] & 15) < 10) v = v * 10 + (s[_i++] & 15);
            if (_neg) v = -v;

            if (v == tar) {
                out << i;
                goto next;
            }
            if (v > tar) break;
        }
        out << -1;
        next:;
    }
    out.flush();
    exit(0);
    return 0;
}();

class Solution {
public:
    int search(vector<int>, int) { return 0; }
};

真是应了书上那句话,程序长的运行效率不一定低。

标签:二分,return,target,nums,int,LeeCode,left,例题,out
From: https://www.cnblogs.com/apeiriaDolce/p/17207980.html

相关文章

  • 1460. 我在哪?(二分,哈希)
    https://www.acwing.com/problem/content/167/n为100,因此对于我们这种枚举k值,枚举两个子串起点来判定是否存在相同子串的暴力做法O(N^4)是可以过的#include<iostream>#......
  • 二分
    情况导入如果在生活中,有一个人,让你猜在\(1\)到\(100\)之间的一个数,你该怎么猜?假设答案是\(20\),那我们应该这样猜:先猜\(50\),大了。随后猜\(25\),还是大了。再猜......
  • 二分法查找
    原理一个数据有升序的数组,每次取中间元素比较,如果大于需要查找的元素,则去后面数据,中间数据作为起点最后数据作为终点再定中间数据比较。如果小于需要查找的数据,则取前面......
  • 二分图
    最大匹配最基本的东西,可以用dinic在\(\mathcal{O}(m\sqrtn)\)的时间内解决。Hall定理判断二分图是否存在完美匹配的定理。默认左部点数小于等于右部点数,定义\(N......
  • 整体二分板子
    P3834可持久化线段树2静态区间第\(k\)小。存个不带修整体二分板子。离散化,拿树状数组维护一下元素出现次数。假设当前区间内所有答案都是\(mid\)。实时更新,这样......
  • 算法基础课笔记:第一章,基础算法 排序 + 二分
    这节课的内容排序快排归并排序二分整数二分浮点数二分如何提高自己敲模板的熟练度呢?反复的练,孰能生巧。重复3-5次。快排1.确定分界点2.调整区......
  • 【LeeCode】350. 两个数组的交集 II
    【题目描述】给你两个整数数组 ​​nums1​​ 和 ​​nums2​​ ,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致......
  • 【LeeCode】349. 两个数组的交集
    【题目描述】给定两个数组 ​​nums1​​ 和 ​​nums2​​ ,返回 它们的交集 唯一 的。我们可以 不考虑输出结果的顺序 。​​​​https://leetcode.cn/problems/i......
  • 二分法
      #include<iostream>usingnamespacestd;constintN=1e5+10;inta[N],st[N];intnum=0;intmain(){intn,q;cin>>n>>q;for(inti=1;i<=n;i++){cin>>a[i];......
  • 整数二分的边界条件
     有单调性的题目一定可以二分,没有单调性的可能可以二分,二分和单调性没有直接关系。整数二分的本质是边界,整个区间可以一份为二,一半满足一半不满足,则二分即可以找前一半......