题目描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0
时间限制:3秒 空间限制:32768K
最差的方式就是遍历,得到最小的值——>时间复杂度为O(n)
import java.util.ArrayList;
public class Solution {
public int minNumberInRotateArray(int [] array) {
if(array.length == 0)
return 0;
//最简单且最没有啥技巧的方式:
int min = 2147483647;
for(int i=0;i<array.length;i++){
if(array[i]<min)
min = array[i];
}
return min;
}
}
//第二种:稍复杂——>时间复杂度nLog(n)
//前几天学了堆,把数组想象成堆结构,小的数向上调整
//从第一个数据开始;
import java.util.ArrayList;
public class Solution {
public int minNumberInRotateArray(int [] array) {
if(array.length == 0)
return 0;
int i,t;
for(i=0; i<array.length; i++){
while(array[i] < array[(i-1)/2]){//子节点比父节点小,交换
t = array[i];
array[i] = array[(i-1)/2];
array[(i-1)/2] = t;
i = (i-1)/2; //新的数继续和前面的父节点比较
}
}
return array[0];//经过堆调整后,得到数组首部就是最小值
}
}
1.堆排介绍
1.1 满二叉树:左右两个孩子全有
1.2 完全二叉树:如果不是满二叉树,则子树是从左往右补齐的也是完全二叉树
1.3 一个数组可以想象成一颗完全二叉树
左子:index=2*i+1
右子:index=2*i+2
索引 i 的父节点下标:(i-1)/2
1.4 堆——完全二叉树
大根堆:在一棵完全二叉树中,任何一棵子树的最大值都是子树的头部
小根堆:在一棵完全二叉树中,任何一棵子树的最小值都是子树的头部
1.5 数组——>大根堆
1.6 数组建立大根堆时间复杂度分析:
完全二叉树:N个数,高度Log(N);
每加入一个数,其本质是与它的上一层做比较,所以加入数的时间复杂度是O(Log(N))
举例:i加入到i-1所组成的满二叉树中,它需要的时间复杂度是Log(i-1),由此总的为Log1+Log2+Log3……LogN-1; —>O(N)
1.7 大根堆是一个往上调整的过程,不断与父节点比较交换,这个过程叫做heapInsert.
public static void heapInsert(int[] arr, int index) {
while(arr[index] > arr[(index-1)/2]){//与父节点比较
swap(arr,index ,(index-1)/2);
index = (index-1)/2;
}//直到index=0或者小于父节点,结束
}
1.8 当某个子树的头部数据发生了变化,向下调整,过程称为heapify
public static void heapify(int[] arr, int index, int size) {
int left = 2*index+1;
while(left<size){
int largest = left+1<heapSize && arr[left+1]>arr[left]?left+1:left;//左右孩子先比较,得出最大值的下标
inr largest = arr[largest]>arr[index]?largest:index;
if(largest == index){
break;
}
swap(arr,largset,index);
left= 2*index+1;
}
1.9 堆的用处(非常有用!!!)
输入一串数组,随时求平均值
大根堆里堆顶放所有值的最大值,小根堆堆顶放所有值的最小值,进去之后,大根堆和小根堆按照自身规则调整。
来一个数先于大根堆比较,大于大根堆的放小根堆,小于大根堆的放大根堆,而且只要某一边比另一边大于1,就把数多的堆顶弹到另一个数少的根堆里。
大根堆调整后,并不一定是有序的。只是建堆过程:O(LogN), 堆排序O(NLogN)
①但唯一能确定的是,堆顶肯定是最大的,
所以先把堆顶与最后一个数交换,然后最后一个值固定不动,看成是数组长度已经少一个。