IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 剑指offer53(二分的应用) -> 正文阅读

[数据结构与算法]剑指offer53(二分的应用)

接下来的这几个题目是以二分查找算法为基础,考察该算法的灵活应用
题目一:
在这里插入图片描述
解析:
在排序的数组中查找数字,我们首先相当的是二分查找.然后要统计target在数组中出现的次数,我们不妨找到第一个target的下标first,然后找到最后一个target的下标last,次数即为last-first+1.
代码:

//找目标值第一次出现
int GetFirstK(vector<int> data, int k, int l, int r) //k即为目标
    {
        int mid = 0;
        if (l > r)
            return -1;
        while (l <= r)
        {
            mid = l + ((r-l) >> 1);
            if (data[mid] == k) //若找到
            {
                //是否为数组第一个数字或数组前一个数字不等于k
                if (mid == 0 || (mid > 0 && data[mid-1] != k))
                {
                    return mid;//找到了第一个目标值
                }
                //数组中前一个数字等于k
                else if (mid > 0 && data[mid-1] == k)//
                {
                    r = mid - 1;
                }
            }
            else if (data[mid] > k)
            {
                r= mid - 1;
            }
            else
            {
                l = mid + 1;
            }
        }
        return -1; //未找到
    }
    //找目标值最后一次出现
    int GetLastK(vector<int> data, int k , int l, int r)
    {
        int mid = 0;
        if (l > r)
            return -1;
        while (l <= r)
        {
            mid = l + ((r-l) >> 1);
            if (data[mid] == k) //若找到
            {
                //数组中最后一个数字或数组中后一个数字不等于目标值
                if (mid == data.size()-1 || (mid < data.size()-1 && data[mid+1] != k))
                {
                    return mid; //找到了最后一个目标值
                }
                // 数组中后一个数字等于目标值
                else if (mid < data.size()-1 && data[mid+1] == k)
                {
                    l = mid + 1;
                }
            }
            else if (data[mid] > k)
            {
                r = mid - 1;
            }
            else
            {
                l = mid + 1;
            }
        }
        return -1; //未找到
    }
    int GetNumberOfK(vector<int> data ,int k) {
        if (0 == data.size())
            return 0;
        int len = data.size();
        int first = GetFirstK(data, k, 0, len-1);
        int last = GetLastK(data, k, 0, len-1);
        cout << first << endl;
        cout << last << endl;
        if (first > -1 && last > -1)
        {
            return (last - first + 1);
        }
        return 0;
    }

题目二:
在这里插入图片描述
分析:
方法1:
遍历数组,对数组求和为sum1; 利用求和公式对数字0~n-1求和为sum2, 缺失的数字即为sum2 - sum1.
方法2:: 在排序的数组中长度n-1,数字范围为0~n-1(n个).二分查找,碰到的第一个数字和它的下标不相等的即为缺失的数字;若相等, l = mid + 1
如: 长度为5, 数字范围为0~5
数字: 0 1 3 4 5
下标: 0 1 2 3 4
2即为缺失的数字.

代码:

//0~n-1(数字范围) 数组长度为n-1  有序 
	int GetMissingNum(const int * num, int len)
	{
		if (num)
		{
			int l = 0;
			int r = len - 1;
			while (l <= r)
			{
				int mid = l + ((r-l) >> 1);
				if (num[mid] != mid)//找到第一个数字与下标不等的
				{
				// 数组中前一个数字与下标相等
					if (mid == 0 || (mid > 0 && num[mid-1] == mid - 1))
					{
						return mid;
					}
					else
					{
						r = mid - 1;
					}
				}
				else //相等 向后缩小查找范围
				{
					l = mid + 1;
				}
			} 
		} 
		return -1;
	} 

题目三:
在这里插入图片描述
解析:
排序数组中寻找数值等于下标的,用二分法.若数值等于下标,找到;若数值>下标,r = mid-1;若数值<下标,l = mid + 1;
代码:

	// 数组中数值与下标相等的元素 无重复数字 
	int GetNumberSameAsIndex(const int * arr, int len)
	{
		if (arr)
		{
			int l = 0;
			int r = len - 1;
			while (l <= r)
			{
				int mid = l + ((r-l) >> 1);
				if (arr[mid] == mid) //找到
				{
					return mid;
				}
				else if (arr[mid] > mid)//数值>下标
				{
					r = mid - 1;
				}
				else     // 数值<下标
				{
					l = mid + 1;
				}
			}
		}
		return -1;
	 } 

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-11-09 19:49:07  更:2021-11-09 19:52:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 10:28:20-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码