首页 > 编程语言 >面试之基础算法题:求一个数字在给定的已排序数组中出现的起始、终止索引号(Java版)

面试之基础算法题:求一个数字在给定的已排序数组中出现的起始、终止索引号(Java版)

时间:2022-11-01 10:31:48浏览次数:49  
标签:nStart Java target int nEnd 索引 nMid 排序


题目

给定一个升序的整数数组,查找某一个值在数组中出现的索引号,例如,输入数组​​[2, 3, 3, 4, 4, 5]​​​;查找的数是3,则返回​​[1, 2]​​。时间复杂度要求为O(logN)。

思路

基本上大致思考一番,就知道可以用二分查找法求解。
然后因为java不能在一个方法里面返回两个int常量,当然返回一个​​​List<Integer>​​​另当别论,此处的思路就是两个查找方法,分别查找起始索引和终止索引。
起始索引:
起始索引的定位,首先比较中间的数和要查找的数 target,如果 target 小于中间的数,那么在数组的左半部分继续查找,如果 target 大于中间的数,在数组的右半部分继续查找;如果 target 和中间的数相等,那么比较中间数字的前一个数字是否和 target 相等,如果不相等,那么当前的中间索引就是起始索引,如果相等,那么继续在前半部分查找;
类似地,定位终止索引时,如果 target 和中间的数相等时,那么比较中间数字的后一个数字是否和 target 相等,如果不相等,那么当前的中间索引就是终止索引,如果相等,那么继续在后半部分查找。

实现

package algorithm.interview;

/**
* Author: Johnny
* Date: 2018/5/15
* Time: 22:02
* 给定一个升序的整数数组,查找某一个值在数组中出现的索引号,例如,输入数组2,3,3,4,4,5;查找的数是3,则返回1,2。时间复杂度要求为O(logN)
*/
public class GetFirstLastIndex {
public static void main(String[] args) {
int[] sortedArray = {1, 1, 2, 3, 3, 6, 6, 6, 6, 9, 9, 10};
int length = sortedArray.length;
int target = 6;
System.out.println(getFirstTarget(sortedArray, length, target, 0, length - 1));
System.out.println(getSecondTarget(sortedArray, length, target, 0, length - 1));
}

/**
* 寻找开始索引
*/
static int getFirstTarget(int[] array, int n, int target, int nStart, int nEnd) {
if (nStart > nEnd) {
// 返回-1表示没有待查询的元素
return -1;
}
// 中间索引
int nMid = nStart + ((nEnd - nStart) >> 1);
int nMidData = array[nMid];

while (nStart <= nEnd) {
if (target > nMidData) {
nStart = nMid + 1;
} else if (target < nMidData) {
nEnd = nMid - 1;
} else {
if ((target != array[nMid - 1] && nMid > 0) || nMid == 0) {
return nMid;
} else {
nEnd = nMid - 1;
}
}
// 更新中间值得索引和值
nMid = nStart + ((nEnd - nStart) >> 1);
// 数组越界判断
if (nMid < 0) {
return -1;
}
nMidData = array[nMid];
}
return -1;
}

/**
* 寻找结束索引
*/
static int getSecondTarget(int[] array, int n, int target, int nStart, int nEnd) {
if (nStart > nEnd) {
return -1;
}
// 中间索引
int nMid = nStart + ((nEnd - nStart) >> 1);
int nMidData = array[nMid];

while (nStart <= nEnd) {
if (target > nMidData) {
nStart = nMid + 1;
} else if (target < nMidData) {
nEnd = nMid - 1;
} else {
if ((target != array[nMid + 1] && nMid < n) || nMid == n - 1) {
return nMid;
} else {
nStart = nMid + 1;
}
}
//更新中间值得索引和值
nMid = nStart + ((nEnd - nStart) >> 1);
if (nMid < 0) {
return -1;
}
nMidData = array[nMid];
}
return -1;
}
}

变形

上面的问法可以经过变形,换一种表现形式来提问:

  1. 假设给定一个有序的整型数组arr,以及整数 k,问k在数组中出现几次?
    根据上面求得的first_index和last_index,即可得到出现次数为: ​​​(last_index - first_index) + 1​​。

参考


标签:nStart,Java,target,int,nEnd,索引,nMid,排序
From: https://blog.51cto.com/u_15851118/5811989

相关文章

  • java操作http请求的三种方式
    java操作http请求的三种方式一、HttpClient步骤:1.获取一个Http客户端CloseableHttpClienthttpClient=HttpClients.createDefault();2.创建一个请求HttpGethttpGet......
  • Java 基于 SpringCloud 数据中台 ETL 工具,可以进行多种常见数据库之间的数据或结构迁
    基于SpringCloud数据中台ETL工具,可以进行多种常见数据库之间的数据或结构迁移提供源端数据库向目的端数据库的批量迁移同步功能,支持数据的全量和增量方式同步。包括:......
  • Java多线程(7):JUC(上)
    您好,我是湘王,这是我的博客园,欢迎您来,欢迎您再来~ 前面把线程相关的生命周期、关键字、线程池(ThreadPool)、ThreadLocal、CAS、锁和AQS都讲完了,现在就剩下怎么来用多线程了......
  • JavaScript中Array.from()方法的用法
    1.介绍作用:将一个伪数组对象或者可迭代的任意对象转换为一个真正的数组语法:Array.from(arrayLike[,mapFunction[,thisArg]])arrayLike:必传参数,指定需要转换为数......
  • Java-什么是多态,多态的具体体现有那些?
    多态:方法或者对象有多种形态,是OOP的第三大特征,是建立在封装和继承之上的多态的具体体现:方法多态重载体现多态重写体现多态对象多态对象的编译类型和运行类型可......
  • MongoDB 索引笔记
    索引(Index)合适的索引可以大大提高数据库搜索性能集合层面的索引支持复合键索引可以对多个字段进行排序复合索引:(A,B,C)可以支持的索引:{A},{A,B},{A,B,C}......
  • Java-equals和“==”的区别
    “==”是比较运算符,可以用于判断基本数据类型是否相等,当用于判断引用类型的时候,比较的对象的内存地址是否相同equals是Object类当中的方法,不可以用于判断基本数据是否相......
  • 学习java的第二天
    java语法学习注释,标识符,关键字写代码时一定写注释这是一个良好的习惯单行注释:“//”这是一个当行注释多行注释:"/*+回车"这是一个多行注释文档注释:"/**+......
  • java 中的final关键字
    final关键字是最终的意思,可以修饰类、变量、方法,在使用时具有如下特点:1.被final修饰的类,不能被继承权限修饰符finalclass类名{}2.被final修饰的方法,不能被重写(覆......
  • SAP Java Connector 错误 - JCO_ERROR_COMMUNICATION
    我运行SAPJavaConnector自带的SimpleCall例子程序时,遇到如下错误消息:Exceptioninthread"main"com.sap.conn.jco.JCoException:(102)JCO_ERROR_COMMUNICATION......