面试之基础算法题:求一个数字在给定的已排序数组中出现的起始终止索引号(Java版)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面试之基础算法题:求一个数字在给定的已排序数组中出现的起始终止索引号(Java版)相关的知识,希望对你有一定的参考价值。
题目
给定一个升序的整数数组,查找某一个值在数组中出现的索引号,例如,输入数组[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;
变形
上面的问法可以经过变形,换一种表现形式来提问:
- 假设给定一个有序的整型数组arr,以及整数 k,问k在数组中出现几次?
根据上面求得的first_index和last_index,即可得到出现次数为: (last_index - first_index) + 1
。
参考
以上是关于面试之基础算法题:求一个数字在给定的已排序数组中出现的起始终止索引号(Java版)的主要内容,如果未能解决你的问题,请参考以下文章
归并排序(归并排序求逆序对数)--16--归并排序--Leetcode面试题51.数组中的逆序对