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

题目描述

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

解决思路

写两个二分查找分别找第一个和最后一个该数字,然后可直接出计算有几个该数字。时间复杂度为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. Cache专用: SoftReference

    SoftReference的语义就是当内存不够用的时候,GC会回收SoftReference所引用的对象.所以,在memory sensitive的程序中将某些大型数据设置成SoftReference ...

  2. JQuery中bind和unbind函数与onclick绑定事件区分

    JQuery中bind和unbind函数转载:   https://blog.csdn.net/liucheng417/article/details/51131982 页面代码: <body& ...

  3. es6初级之解构----之二 及 键值反转实现

    1.解构: 不定参数,扩展表达式 let arr = [100, 201, 303, 911]; let [one, ...others] = arr; console.log(others.leng ...

  4. spark遇到的错误1-内存不足

    原来的代码: JavaRDD<ArticleReply> javaRdd = rdd.flatMap(new FlatMapFunction<String, ArticleReply ...

  5. MySQL更新优化(转)

    通常情况下,当访问某张表的时候,读取者首先必须获取该表的锁,如果有写入操作到达,那么写入者一直等待读取者完成操作(查询开始之后就不能中断,因此允许读取者完成操作).当读取者完成对表的操作的时候,锁就会 ...

  6. KMP算法next数组求解

    关于KMP算法,许多教材用的是递推式求解,虽然代码简洁,但是有些不好理解,这里我介绍一种迭代求next数组的方法 KMP算法关键部分就是滑动模式串,我们可以每次滑动一个单位,直到出现可能匹配的情况,此 ...

  7. Go语言学习笔记(1)

    包 package 声明包,import 导入包,导入的包名要用"",包中导出的名字以大写字母打头. package main import "fmt" imp ...

  8. MySQL字符集介绍及配置

    目录 1.MySQL编码集 2.修改字符集 3.MySQL数据库中字符集转换流程 4.修改现有字符集 1.MySQL编码集 查看MySQL支持的字符集 mysql> show character ...

  9. php缩小png图片时,不损失透明色的办法

    做站点时,通常要将图片缩小成合适的尺寸,jpg图片缩小比较容易,png图片如果带了透明色的话,按照jpg的方式来缩小的话,就会造成透明色损失.那么如何处理,才能保存透明色呢? 主要是利用gd库的两个方 ...

  10. week05 05restful api

    和第一个项目一样 然后去App.js注册一下 但是呢 新闻是写死在 现在主要输调通前端client和后端server 持续获取新闻 至于真假先不考虑 下面我们回到前端NewsPanel 这个reque ...