旋转数组找最小
题目描述: 输入一个旋转数组,找出这个数组中的最小值,要求时间复杂度为(logn)
题目分析:
- 旋转数组:指的是将一个有序的数组的前一部分移动到后一部分,如[1,2,3,4,5]的一个旋转数组为:[2,4,5,1,2]
- 时间复杂度为logn:立刻想到二分法(折半查找)
- 二分查找一般需要个固定的比较值,然而这道题却没有,怎么办?根据题意具体分析有以下几种情况:
(1)[4,5,6,1,2,3],arr[mid]>arr[first],故min在区间[mid+1,last]
(2)[4,5,1,2,3] arr[mid]< arr[last],故min在区间[first,mid]
(3)[1,1,1,0,1],则,first,向左移动一位;
代码
import java.util.ArrayList;
public class Solution {
public int minNumberInRotateArray(int [] array) {
if(array.length==0){
return 0;
}
int i=0;//首元素
int j=array.length-1;
while(i<j){
if(array[i]<array[j]){//没有进行旋转的一种特殊情况
return array[i];
}
int mid=(i+j)/2;
if(array[i]<array[mid]){
//要找的最小值必然在右半部分
i=mid+1;
}else if(array[j]>array[mid]){
j=mid;
}else{
i++;
}
}
//特例:只有一个元素
return array[i];
}
}
[1,n]整数数组中找1出现的总个数
题目描述: 求出113的整数中1出现的次数,并算出1001300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数(从1 到 n 中1出现的次数)。
解题思路:
从最低位向最高位依次取出当前值cur,并计算cur的高位high和低位low;
当cur == 0时,出现的1的个数=highi;
当cur ==1时,出现1的个数=highi+(low+1);
其他情况,出现1的个数=(high+1)*i;
最后计算从最低位到最高位的总和
public class Solution {
public int NumberOf1Between1AndN_Solution(int n) {
int count=0;
for(int i=1;i<=n;i*=10){
int high=n/(i*10);
int low=n%i;
int curVal=n/i%10;
if(curVal==0){
count+=high*i;
}else if(curVal==1){
count+=high*i+(low+1);
}else{
count+=(high+1)*i;
}
}
return count;
}
}
在二维数组中查找值
题目描述: 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
题目分析:
从左下角元素(curVal)开始寻找,这个元素是这行中最大的数,这列中最小的数,如果target>curVal,只能从下一列中开始寻找,即col++,如果target< curVal,只能从上一行中寻找,即row–;注意 col<=cols-1;row>=0;
public class Solution {
public boolean Find(int target, int [][] array) {
//最后一列的中间值
int rows=array.length;//二维数组的行数
int cols=array[0].length;//二维数组的列数
if(rows==0){
return false;
}
if(cols==0){
return false;
}
//左下角
int row=rows-1;
int col=0;
while(row>=0 && col<=cols-1){
if(array[row][col]<target){
col++;
}else if(array[row][col]>target){
row--;
}else{
return true;
}
}
return false;
}
}