剑指Offer系列(java版,详细解析)11.旋转数组的最小数字
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了剑指Offer系列(java版,详细解析)11.旋转数组的最小数字,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3904字,纯文字阅读大概需要6分钟。
内容图文
题目描述
剑指 Offer 11. 旋转数组的最小数字
难度简单
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2]
为 [1,2,3,4,5]
的一个旋转,该数组的最小值为1。
示例 1:
输入:[3,4,5,1,2]
输出:1
示例 2:
输入:[2,2,2,0,1]
输出:0
注意:本题与主站 154 题相同:https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array-ii/
测试用例
- 功能测试(输入的数组是非递减排序数组的一个旋转,数组中有重复的数字或者没有重复的数字)
- 边界值测试(输入的数组是一个非递减排序的数组,只包含一个数字的数组)
- 特殊输入测试(输入空指针)
题目考点
- 考察应聘者对二分查找的理解。如果遇到从排序的数组中查找数字需要尝试二分查找法。
- 考察应聘者的沟通能力和学习能力。如果面试官提出新的概念,那么我们可以主动和面试官沟通,多问几个问题,把概念弄清楚。
- 考察应聘者思维的全面性。排序数组本身是一个数组旋转的一个特例,另外,我们需要考虑到数组中有相同数字的特例。
解题思路
如果遇到从排序的数组中查找数字需要尝试二分查找法。
我们利用两个指针分别指向数组的第一个元素和最后一个元素,我们可以先找到数组中间的元素,如果该中间元素大于或等于第一个元素,则位于前面的非递减子数组,此时我们就可以把第一个指针指向该中间元素,这样就可以缩小寻找的范围,移动以后,第一个指针依然指向前面的非递减数组;否则属于后面的非递减子数组,此时我们就可以把第二个指针指向该中间元素,移动以后,第二个指针依然指向后面的非递减数组。然后循环下去,最终第一个指针将指向前面子数组的最后一个元素,而第二个指针将会指向后面子数组的第一个元素,而第二个指针指向的刚好是最小的元素。循环结束。
参考解题
/**
* Author:Viper
* Data:2021/3/11
* description:
*/
public class problem11 {
public int minArray(int[] numbers) {
int len =numbers.length;
if(len==0)
return 0;
int i=0,j=len-1;
while(i<j){
int mid = i+(j-i)/2;
if(numbers[mid]<numbers[j])
j=mid;
else if(numbers[mid]==numbers[j])
j--;
else
i=mid+1;
}
return numbers[i];
}
}
补充
如果面试题是要求在排序的数组(或者部分排序的数组)中查找一个数字或者统计某个数字出现的次数, 那么我们都可以尝试 二分查找算法。
强烈建议在准备面试的时候,一定要对各种排序算法的特点烂熟于胸,能够从额外空间消耗、平均时间复杂度和最差时间复杂度等方面去比较他们的优缺点。(特别关注手写快排)
快排算法思想如下:
先在数组中选择一个数字,接下来吧数组中的数字分为两部分,比选择的数字小的数字移到数组的左边,比选择的的数字大的数字移到数组的右边 (善用指针的想法)。然后左右两侧分别递归得到最后结果。
快排算法代码如下:
import java.util.Random;
/**
* 快速排序
*/
public class QuickSort {
/**
* 交换数组中的两个值
* @param array
* @param a
* @param b
*/
public static void swap (int[] array, int a, int b) {
int temp = array[a];
array[a] = array[b];
array[b] = temp;
}
/**
* 分区函数
* 按随机出的基准值分区,将比基准值小放在基准值左边,大的放在基准值右边
* @param data
* @param length
* @param start
* @param end
* @return
* @throws Exception
*/
public static int partition(int data[], int length, int start, int end) throws Exception {
Random random = new Random();
if (data == null || length <=0 || start <0 || end >= length) {
throw new Exception("Invalid Parameters");
}
// 尽量避免极端情况,每次都是以最后一个数字作为基准值,在start和end之间随机出一个数
int index = start + random.nextInt(end - start + 1);
// 将比较的值放在数组的最后
swap(data, index, end);
// 定义一个指针,指向所有换序之后所有比基准值都小的数据的最右边,最后最指向基准值应该在位置
int small = start - 1;
for (int i = start; i < end; i++) {
if (data[i] < data[end]) {
small++;
// 避免原来就是有序数列的无用交换
if (small != i) {
swap(data, small, i);
}
}
}
// 把基准值放在中间
small++;
swap(data, small, end);
return small;
}
/**
* 利用分区函数实现快速排序
* 递归
* @param data
* @param length
* @param start
* @param end
* @throws Exception
*/
public static void quickSort(int[] data, int length, int start, int end) throws Exception {
// 当只剩一个数的时候就不用递归了
if (start == end) {
return;
}
int index = partition(data, length, start, end);
// 防止异常
if (index > start) {
quickSort(data, length, start, index - 1);
}
if (index < end) {
quickSort(data, length, index + 1, end);
}
}
}
内容总结
以上是互联网集市为您收集整理的剑指Offer系列(java版,详细解析)11.旋转数组的最小数字全部内容,希望文章能够帮你解决剑指Offer系列(java版,详细解析)11.旋转数组的最小数字所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。