参考大佬的链接 点击即转
一.查找
题目名称 |
---|
1.二维数组中的查找 |
2.旋转数组的最小数字(二分查找) |
3.数字在排序数组中出现的次数 |
4. 0~n中缺失的数字 |
1.二维数组中的查找
//折半查找 超时
public class one {
public static void main(String[] args) {
int [][] array = {{1,2,4,6,9},
{2,4,8,9,10},
{4,5,10,12,13},
{5,7,11,15,20},
{6,9,15,17,21}};
boolean a = Find(3,array);
System.out.println(a);
}
public static boolean Find(int target, int[][] array) {
int rowLength = array.length;
int rowMin = 0;
int rowMax = rowLength - 1;
int rowMid = (rowMax - rowMin) / 2;
int columnLength = array[0].length;
int columnMin = 0;
int columnMax = columnLength - 1;
int columnMid = (columnMax - columnMin) / 2;
int mid = array[rowMid][columnMid];
while (true) {
if (target < mid) {
rowMax = rowMid;
columnMax = columnMid;
rowMid = (rowMax - rowMin) / 2;
columnMid = (columnMax - columnMin) / 2;
if(array[rowMax][columnMax] == array[rowMin][columnMin]){
return false;
}
} else if (target > mid) {
rowMin = rowMid;
columnMin = columnMid;
rowMid = (rowMax - rowMin) / 2;
columnMid = (columnMax - columnMin) / 2;
if(array[rowMax][columnMax] == array[rowMin][columnMin]){
return false;
}
}
else{
return true;
}
}
}
}
AC版
public class one {
public static void main(String[] args) {
int [][] array = {{1,2,4,6,9},
{2,4,8,9,10},
{4,5,10,12,13},
{5,7,11,15,20},
{6,9,15,17,21}};
boolean a = Find(3,array);
System.out.println(a);
}
public static boolean Find(int target, int[][] array) {
if (array == null || array.length == 0 || array[0].length == 0){
return false;
}
int rowMax = array.length - 1;
int rowCul = array.length - 1;
int columnMax = array[0].length - 1;
int columnCul = 0;
while (true) {
if (rowCul < 0 | rowCul > rowMax | columnCul > columnMax | columnCul < 0 ) {
return false;
}
else if(target == array[rowCul][columnCul]){
return true;
}else if (target > array[rowCul][columnCul]) {
columnCul++;
}
else{
rowCul--;
}
}
}
}
2.旋转数组的最小数字(二分查找)
大佬讲的很详细 代码有点杂 容易理解点击即转
/**
* @auther ZhangGang
* @date 2020/1/5 20:47
*/
public class Solution {
public static void main(String[] args) {
int[] data = {3, 4, 5, 1, 2};
System.out.println(minNumberInRotateArray(data));
}
public static int minNumberInRotateArray(int[] numbers) {
if (numbers == null || numbers.length <= 0) {
return -1;
}
int index1 = 0;
int index2 = numbers.length - 1;
// 把indexMid初始化为index1的原因:
// 一旦发现数组中第一个数字小于最后一个数字,表明该数组是排序的
// 就可以直接返回第一个数字了
int indexMid = index1;
while (numbers[index1] >= numbers[index2]) {
// 如果index1和index2指向相邻的两个数,
// 则index1指向第一个递增子数组的最后一个数字,
// index2指向第二个子数组的第一个数字,也就是数组中的最小数字
if (index2 - index1 == 1) {
indexMid = index2;
break;
}
indexMid = (index1 + index2) / 2;
// 特殊情况:如果下标为index1、index2和indexMid指向的三个数字相等,则只能顺序查找
if (numbers[index1] == numbers[indexMid] && numbers[indexMid] == numbers[index2]) {
return GetMinInOrder(numbers, index1, index2);
}
// 缩小查找范围
if (numbers[indexMid] >= numbers[index1]) {
index1 = indexMid;
} else if (numbers[indexMid] <= numbers[index2]) {
index2 = indexMid;
}
}
return numbers[indexMid];
}
public static int GetMinInOrder(int[] numbers, int index1, int index2) {
int result = numbers[index1];
for (int i = index1 + 1; i <= index2; ++i) {
if (result > numbers[i]) {
result = numbers[i];
}
}
return result;
}
}
代码简洁 不易理解
/**
* @auther ZhangGang
* @date 2020/1/5 20:47
*/
public class two {
public static void main(String[] args){
int[] data = {3,4,5,1,2};
System.out.println(minNumberInRotatedArray(data));
}
public static int minNumberInRotatedArray(int[] data){
if(data==null || data.length==0)
{
return -1;
}
int left = 0;
int right = data.length-1;
int mid;
while(left<right){
mid = left+(right-left)/2;
//left < right
//这里是理解难点 *****
if(data[left]<data[right]){
return data[left];
}
//left > right
else if(data[left]>data[right]){
if(data[mid]>=data[left]){
left = mid + 1;
}
else{
right = mid;
}
}
//left = right
else{
if(data[left]<data[mid]){
left = mid + 1;
}
else if(data[left]>data[mid]){
right = mid;
}
else{
left = left+1;
right = right-1;
}
}
}
return data[right];
}
}
3.数字在排序数组中出现的次数
有点复杂 刚开始没看明白
易于理解 思路清晰
/**
* @auther ZhangGang
* @date 2020/1/5 21:11
*/
public class Solution {
public static void main(String [] args){
int arr [] = {1, 2, 3, 3, 3, 3, 4, 7, 9, 9, 9, 11};
System.out.println(GetNumberOfK(arr,3));
}
public static int GetNumberOfK(int [] array , int k) {
int start = getStartK(array,k);
if(start == -1){
return 0;
}
int end = getEndK(array,start,k);
return end - start + 1;
}
private static int getStartK(int[] array, int k) {
if (array == null || array.length == 0)
{
return -1;
}
int left = 0;
int right = array.length - 1;
int mid;
while(left <= right){
if (left == right){
if (array[left] == k){
return left;
}
else{
return -1;
}
}
mid = left + (right - left)/2;
if (array[mid] > k ){
right = mid - 1;
}
else if (array[mid] < k){
left = mid + 1;
}else { //此处满足条件之后,怎么赋值 不好写,*******
right = mid;
}
}
return -1;
}
private static int getEndK(int[] array, int start, int k) {
//此处不需要判断 是否为空,
// if (array == null || array.length == 0){
// return 0;
// }
int left = start;
int right = array.length-1;
int mid;
while(left <= right){
if (left == right){
if (array[left] == k){
return left;
}
else{
return -1;
}
}
mid = left + (right - left + 1)/2;
if (array[mid] > k ){
right = mid - 1;
}
else if (array[mid] < k){
left = mid + 1;
}else { //此处满足条件之后,怎么赋值 不好写,*******
left = mid;
}
}
return -1;
}
}
4.0~n中缺失的数字