第三节 二分
介绍
故事分享🏬:
有一天小明到图书馆借了 N 本书,出图书馆的时候,警报响了,于是保安把小明拦下,要检查一下哪本书没有登记出借。小明正准备把每一本书在报警器下过一下,以找出引发警报的书,但是保安露出不屑的眼神:你连二分查找都不会吗?于是保安把书分成两堆,让第一堆过一下报警器,报警器响;于是再把这堆书分成两堆…… 最终,检测了 logN 次之后,保安成功的找到了那本引起警报的书,露出了得意和嘲讽的笑容。于是小明背着剩下的书走了。 从此,图书馆丢了 N - 1 本书。
保安怎么知道只有一本书📖没有登记出借,万一全部都没有登记呢?
这个故事其实说出了二分查找需要的条件
- 用于查找的内容逻辑上来说是需要有序的
- 查找的数量只能是一个,而不是多个
比如在一个有序的数组并且无重复元素的数组中,例如[1, 2, 3, 4, 5, 6],需要查找3的位置就可以使用二分查找。
在二分查找中,目标元素的查找区间的定义十分重要,不同的区间的定义写法不一样
因为查找的区间是不断迭代的,所以确定查找的范围十分重要,主要就是左右区间的开和闭的问题,开闭不一样,对应的迭代方式也不一样,有以下两种方式:
-
左闭右闭
[left, right]
-
左闭右开
[left, right)
例子
题目如下:
给定一个 \(n\) 个元素有序的(升序)整型数组 \(nums\) 和一个目标值 \(target\),写一个函数搜索 \(nums\) 中的 \(target\),如果目标值存在返回下标,否则返回 \(-1\)。
示例一:
输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4
示例二:
输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1
提示:
- 你可以假设 \(nums\) 中的所有元素是不重复的。
- \(n\) 将在 \([1, 10000]\) 之间。
- \(nums\) 的每个元素都将在 \([-9999, 9999]\) 之间。
错题整理
- 进制与编码
- 已知 \(A=11001010B\),\(B=00001111B\),\(C=01011100B\),A | B & C = ( )B。
A. 11001110
B. 01110110
C. 11101110
D. 01001100
题解
"∧"和"∨"相当于计算机程序里的 \(and\) 和 \(or\),在这里可以当作按位与和按位或理解。"∧" 是 \(and\),"∨" 是 \(or\),运算时,"∧" 优先级高于 "∨"。
- \(C\) 语言环境下,\(-1\) 存储在 \(int\) 类型 \(32\) 位变量里应为( )
A. 11111111111111111111111111111111
B. 10000000000000000000000000000000
C. 10000000000000000000000000000001
D. 00000000000000000000000000000001
题解
在C++语言环境下,\(-1\) 存储在 \(int\) 类型 \(32\) 位变量中,应为选项 \(A.11111111111111111111111111111111\)。
在二进制补码表示中,\(-1\) 用全部位都为 \(1\) 的补码表示。对于 \(32\) 位的 \(int\) 类型变量,其二进制表示为 \(32\) 个 \(1\),即 \(11111111111111111111111111111111\)。
- 采用32*32点阵的汉字字模,存放1600个汉字信息需要的存储容量是( )KB。
A. 25
B. 200
C. 800
D. 1600
题解
点阵的大小表示每一个汉字的大小,32×32的点阵表示每一个字需要 \(32 × 32 = 1024\) bit来存储。又因为 \(1KB = 1024 Byte=1024 × 8 bit\),所以存放 \(1600\) 个汉字需要 \(1600 × 1024 / (1024 × 8) = 200 KB\)。
- 分辨率为800*600、16位色的位图,存储图像信息所需的空间为( )KB.
A. 937.5
B. 4218.75
C. 4320
D. 2880
题解
分辨率为 \(800 * 600\)、\(16\)位色的位图,存储图像信息所需的空间计算如下:
每个像素占用 \(16\) 位,即 \(2\) 个字节。
图像的总像素数为 \(800 * 600 = 480,000\) 像素。
因此,存储图像信息所需的空间为 \(480,000 * 2 = 960,000\) 字节。
将字节转换为 \(KB\),可以除以 \(1024\),即 \(960,000 / 1024 ≈ 937.5 KB\)。
所以,正确答案是 \(A. 937.5 KB\)。
- 在计算机里用四个字节来表示有符号的整数,那么整数的范围最大的是( ) 。
A. \(− 2 ^ {31} + 1\) 到 \(2 ^ {31} - 1\)
B. \(− 2 ^ {31}\) 到 \(2 ^ {31} - 1\)
C. \(− 2 ^ {32}\) 到 \(2 ^ {32}\)
D. \(- 2 ^ {31} + 1\) 到 \(2 ^ {31}\)
题解
在计算机中有符号整数,二进制位第一位用来表示符号。负数用补码表示,而负数的补码是其反码 \(+1\)。在 \(4\) 字节 \(32\) 位中,补码能表示的最小值为 \(-2^31\),即\(1000…000(31 位 0)\)
- 已知二进制下,\(A=11001010,\)B=00001111,\(C=01011100\),则\(A∨B∧C=\)( )
A. \(11001110\)
B. \(01110110\)
C. \(11101110\)
D. \(01001100\)
题解
根据位运算的优先级,先进行与运算(&),再进行或运算(|)。
A = 11001010
B = 00001111
C = 01011100
B & C = 00001100
A | (B & C) = 11001110
所以,A∨B∧C 的结果是 11001110。
- 一个 \(int\) 类型的值,做以下哪个操作,一定会变回原来的值?()
A. 左移 \(3\) 位,再右移 \(3\) 位。
B. 右移 \(3\) 位,再左移 \(3\) 位。
C. 按位或 \(7\),再按位与 \(-8\)。
D. 按位异或 \(7\),再按位异或 \(7\)。
题解
A选项:左移 \(3\) 位再右移 \(3\) 位,会将原来的值右侧的位丢失,无法恢复原值。
B选项:右移 \(3\) 位再左移 \(3\) 位,同样会将原来的值左侧的位丢失,无法恢复原值。
C选项:按位或 \(7\),再按位与 \(-8\),会改变原来的值,因为按位或操作会将右侧的位置为 \(1\),按位与操作会根据第二个操作数的位来决定结果的对应位,所以无法恢复原值。
本文来自博客园,作者:So_noSlack,转载请注明原文链接:https://www.cnblogs.com/So-noSlack/p/17546539.html