1,概念
数组一旦定义,其维数和维界就不再改变。
因此除了结构的初始化和销毁之外,数组只有存取元素和修改元素值的操作。
1)java中定义
float f[][] = new float[6][6];
float []f[] = new float[6][6];
float [][]f = new float[6][6];
float [][]f = new float[6][];
程序设计语言中,数组元素在内存中是一个接着一个线性存放的,通过第一个元素就能访问随后的元素,这样的数组称之为“真数组”。
实现了真数组为Java语言健壮性的特点之一。
2,应用
1)哈希表
把数组的下标设为哈希表的键值(key),而把数组中每一个数字设为哈希表的值(value),有了这样的哈希表,就可以O(1)实现查找。从而快速高效的解决很多问题。
2)二维数组的查找
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
如下,二维数组每行每列递增排序,查找一个数字,找到返回true,否则false
1 2 8 9
2 4 9 12
4 7 10 13
6 8 11 15
解决方案:
方案一:二分查找。
方案二:(推荐)
对于目标数字num_target
,首先选取数组右上角的数字right_num
,
如果right_num == num_target
,返回true;
如果right_num > num_target
,剔除所在列;
如果right_num < num_target
,剔除所在行;
如果查找范围为空,返回false;
public boolean find(int[][] array, int target) {
if (array == null) {
return false;
}
int row = 0;
int column = array[0].length - 1;
while (row < array.length && column >= 0) {
if (array[row][column] == target) {
return true;
}
if (array[row][column] > target) {
column--;
} else {
row++;
}
}
return false;
}
3)旋转数组的最小数字
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非递减排序的数组的一
个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0
思路:利用二分法,找到中间的数,然后和最左边的值进行比较,若大于最左边的数,则最左边从mid开始,
若小于最右边值,则最右边从mid开始。若左中右三值相等,则取mid前后值中较小的数。
public int minNumberInRotateArray(int [] array) {
if (array == null || array.length == 0)
return 0;
int left = 0;
int right = array.length - 1;
int mid = 0;
while (array[left] >= array[right]) {
if(right - left <= 1) {
mid = right;
break;
}
mid = (left + right)/2;
if (array[left] == array[mid] && array[mid] == array[right]) {
if (array[left+1] != array[right-1]) {
mid = array[left+1] < array[right-1] ? left+1:right-1;
} else {
left++;
right--;
}
} else {
if (array[left] <= array[mid]) {
left = mid;
} else {
right = mid;
}
}
}
return array[mid];
}
注意:对于二分查找,如果两个数相同,并且他们中间的数也相同,那么就无法识别出要查找的数字的具体位置,如:{0,1,1,1,1}的旋转:{1,0,1,1,1}。只能用顺序查找方式来实现。
4)顺时针打印矩阵
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵,依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10。
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
思路:
每次打印一圈,循环打印。每圈终止条件是(start,start)(第一圈中止为(1,1),第二圈为(2,2)。
最后一圈判断,即循环条件为matrix[0].length > start * 2 && matrix.length > start * 2
,在中间。
public ArrayList<Integer> printMatrix(int[][] matrix) {
ArrayList<Integer> list = new ArrayList<>();
if (matrix == null)
return list;
int start = 0;
while (matrix[0].length > start * 2 && matrix.length > start * 2) {
printOneCircle(matrix, start, list);
start++;
}
return list;
}
private void printOneCircle(int[][] matrix, int start, ArrayList<Integer> list) {
int endX = matrix[0].length - 1 - start; // 列
int endY = matrix.length - 1 - start; // 行
// 从左往右 (列号大于行号)
for (int i = start; i <= endX; i++)
list.add(matrix[start][i]);
// 从上往下(行号大于列号)
if (start < endY) {
for (int i = start + 1; i <= endY; i++)
list.add(matrix[i][endX]);
}
// 从右往左(判断是否会重复打印)
if (start < endX && start < endY) {
for (int i = endX - 1; i >= start; i--)
list.add(matrix[endY][i]);
}
// 从下往上(判断是否会重复打印)
if (start < endX && start < endY - 1) {
for (int i = endY - 1; i >= start + 1; i--)
list.add(matrix[i][start]);
}
}