题目一 数字在排序数组中出现的个数

题目描述

统计一个数字在排序数组中出现的次数。

解决思路

写两个二分查找分别找第一个和最后一个该数字,然后可直接出计算有几个该数字。时间复杂度为O(logn)。

这里使用二分查找的递归写法,形式可以写得更简洁(见书)。

当输入不符合规则返回-1。注意形参len表示原始数组的长度,在此题目中是必要的。注意特殊输入的处理。

代码

#include <iostream>
using namespace std; int findFirstK(int* num,int len,int k,int beg,int end){
if(beg>end){
return -1;
}
int midIndex=(beg+end)/2;
int midNum=num[midIndex];
if(k<midNum){
return findFirstK(num, len, k, beg, midIndex-1);
}
else if(k>midNum){
return findFirstK(num, len, k, midIndex+1, end);
}
else{
if(midIndex==0||(midIndex>0&&num[midIndex-1]!=k)){
return midIndex;
}
else{
return findFirstK(num, len, k, beg, midIndex-1);
}
}
} int findLastK(int*num,int len,int k,int beg,int end){
if(beg>end){
return -1;
}
int midIndex=(beg+end)/2;
int midNum=num[midIndex];
if(k<midNum){
return findLastK(num, len, k, beg, midIndex-1);
}
else if(k>midNum){
return findFirstK(num, len, k, midIndex+1, end);
}
else{
if(midIndex==len-1||(midIndex<len-1&&num[midIndex+1]!=k)){//此处需要原始数组的长度len
return midIndex;
}
else{
return findLastK(num, len, k, midIndex+1, end);
}
}
} int getKCnt(int *num,int len,int k,int beg,int end){
if(num==nullptr||len<0){
return -1;
}
int cnt = 0;
int fistKIndex=findFirstK(num, len, k, beg, end);
int lastKIndex=findLastK(num, len, k, beg, end);
if(fistKIndex!=-1&&lastKIndex!=-1){
cnt=lastKIndex-fistKIndex+1;
}
return cnt;
} int main(int argc, const char * argv[]) {
int num[]={1,2,3,4,4,4,5,6};
int len=sizeof(num)/sizeof(int);
int k=4;
int kCnt=getKCnt(num, len, k, 0, len-1);
cout<<"The count of K is:"<<kCnt<<endl;
return 0;
}

题目二 0-n-1中缺失的数字

题目描述

一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0-n-1之内。在范围0-n-1内的n个数字中有且只有一个数字不在该数组中,找出这个数字。

解决思路

用二分查找找到数组中第一个树枝和下标不相等的下标,即是缺失数字。时间复杂度为O(logn)。

这里使用递归写法,使用循环写法形式更简洁。

相关知识

当数组不是有序时,可以利用数字0-n-1之和n*(n-1)/2减去 遍历数组得到的数组元素之和,即是缺失数字。由于遍历数组时间复杂度为O(logn),所以总时间复杂度为O(logn)。

代码

#include <iostream>
using namespace std; int findMissNum(int* num,int beg,int end){
if(num==nullptr||end-beg<0){
return -1;
}
int midIndex=(beg+end)/2;
int midNum=num[midIndex];
if(midNum==midIndex){
return findMissNum(num, midIndex+1, end);
}
else if(midNum>midIndex){
if(midIndex==0||num[midIndex-1]==midIndex-1){//注意
return midIndex;
}
else{
return findMissNum(num, beg, midIndex-1);
}
}
else{
return -1;
}
} int main(){
// int num[]={0,1,2,3,4,6,7};
int num[]={1};
int missNum=findMissNum(num, 0, sizeof(num)/sizeof(int)-1);
cout<<"The missing number is:"<<missNum<<endl;
return 0;
}

题目三 数组中数值和下标相等的元素

题目描述

假设一个单调递增数组里的每个元素都是整数且唯一。找出数组中任意一个数值等于其下标的元素。

解决思路

二分查找。时间复杂度为O(logn)。

关于细节很好的

这里使用循环写法。

二分查找的细节 第一个ok,第二、三个还需仔细理解。

参考链接 https://leetcode-cn.com/problems/binary-search/solution/er-fen-cha-zhao-xiang-jie-by-labuladong/









C++代码

#include <iostream>
using namespace std; int findK(int* num,int len){
if(num==nullptr||len<=0){
return -1;
} int l=0;
int r=len-1;
while(l<=r){
int midIndex=(l+r)>>1;
int midNum=num[midIndex];
if(midNum==midIndex){
return midNum;
}
else if(midNum>midIndex){
r=midIndex-1;
}
else{
l=midIndex+1;
}
}
return -1;
} int main(){
int num[]={-1,0,2,3,4,5,6};
// int num[]={0};
int K=findK(num, sizeof(num)/sizeof(int));
cout<<"One of the number which is equal to its index is:"<<K<<endl;
return 0;
}

Java代码

class Solution {
public int search(int[] nums, int target) {
if(nums==null){
return -1;
} int l=0;
int r=nums.length-1;
while(l<=r){
int mid=(l+r)/2;
if(nums[mid]==target){
return mid;
}
else if(nums[mid]<target){
l=mid+1;
}
else{
r=mid-1;
}
}
return -1;
}
}

[剑指Offer]53-在排序数组中查找数字(二分查找)的更多相关文章

  1. 剑指offer——56在排序数组中查找数字

    题目描述 统计一个数字在排序数组中出现的次数.   题解: 使用二分法找到数k然后向前找到第一个k,向后找到最后一个k,即可知道有几个k了 但一旦n个数都是k时,这个方法跟从头遍历没区别,都是O(N) ...

  2. 剑指Offer - 九度1348 - 数组中的逆序对

    剑指Offer - 九度1348 - 数组中的逆序对2014-01-30 23:19 题目描述: 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个 ...

  3. 剑指offer:二维数组中的查找

    目录 题目 解题思路 具体代码 题目 题目链接 剑指offer:二维数组中的查找 题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺 ...

  4. 剑指Offer - 九度1370 - 数组中出现次数超过一半的数字

    剑指Offer - 九度1370 - 数组中出现次数超过一半的数字2013-11-23 03:55 题目描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组 ...

  5. 剑指Offer - 九度1351 - 数组中只出现一次的数字

    剑指Offer - 九度1351 - 数组中只出现一次的数字2013-11-23 01:23 题目描述: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. ...

  6. 剑指 Offer 04. 二维数组中的查找 (思维)

    剑指 Offer 04. 二维数组中的查找 题目链接 本题的解法是从矩阵的右上角开始寻找目标值. 根据矩阵的元素分布特性, 当目标值大于当前位置的值时将row行号++,因为此时目标值一定位于当前行的下 ...

  7. 《剑指offer》 二维数组中的查找

    本题目是<剑指offer>中的题目 二维数组中的查找 题目: 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个 ...

  8. 【Java】 剑指offer(3) 二维数组中的查找

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上 ...

  9. [剑指Offer]5.二维数组中的查找

    题目 在一个二维数组中,每一行都依照从左到右递增的顺序排序,每一列都依照从上到下递增的顺序排序.请完毕一个函数,输入这种一个二维数组和一个整数.推断数组中是否含有该整数. 思路 [算法系列之三十三]杨 ...

  10. 《剑指Offer 1.二维数组中的查找》2019-03-25

    剑指Offer  第一题 题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数 ...

随机推荐

  1. 机器学习进阶-图像基本操作-边界补全操作 1.cv2.copyMakeBoder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_REPLICATE) 进行边界的补零操作 2.cv2.BORDER_REPLICATE(边界补零复制操作)...

    1.cv2.copyMakeBoder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_REPLICATE) 参数说明: i ...

  2. HBase 入门

    使用条件: 海量数据百亿级的行 百万列,  准实时查询 使用场景:  比如金融,交通,电商,移动等 特点: 1:

  3. cxgrid合并值相同的某列

    设置 cxGrid 的某列的 CellMerging 属性可使这一列相同值的单元格合并. 1)cxGridDBTableViewColumn1.Options.CellMerging:=true  2 ...

  4. python语言中的数据类型之元组

    数据类型 元组       tuple 元组:不可变类型 用途:元组就是一个不可变的列表,当需要存不改动的值时可用元组 定义方式:在()内用逗号分隔开多个任意类型的元素 t=(1,2.2,'aa',( ...

  5. Cobbler自动化工具实践

    1.Cobbler Install 安装前准备  /*注:Cobbler需安装在CentOS7机器上面,建议安装Cobbler机器的CentOS7 everything版本*/ 关闭SELinux c ...

  6. 在postgresqlz中查看与删除索引

    查看索引 select * from pg_indexes where tablename='tbname';      或者     select * from pg_statio_all_inde ...

  7. Linux sort命令使用方法

    sort命令在Linux中主要用于对文件进行排序,并将排序结果输出.sort命令输入可以是指定的文件和数据流.本文主要介绍sort命令的基本语法和常见使用实例. sort命令语法 sort命令格式:s ...

  8. 手工获取AWR报告

    AWR(Automatic Workload Repository)报告常用于Oracle数据库性能分析.熟练解读AWR报告有助于快速分析Oracle性能问题.下面主要描述如何手工获取AWR报告. 操 ...

  9. 传输层——TCP报文头介绍

    16位源端口号 16位目的端口号 32位序列号 32位确认序列号 4位头部长度 保留6位 U R G A C K P S H R S T S Y N F I N 16位窗口大小 16位检验和 16位紧 ...

  10. reids遇到问题

    今天重启爬虫服务器在连接redis数据库时突然报错:MISCONF Redis is configured to save RDB snapshots, but it is currently not ...