二维数组
- 一个二维数组,每一行从左到右递增, 每一列从上到下递增。判断数组中是否含有该整数。
- 求二维子数组和的最大值(任意维度子矩阵,固定维度2×2子矩阵)。
- 矩阵原地转置(n×n方阵,m×n矩阵)。
1、思路:(详细参考:http://justjavac.iteye.com/blog/1310178)
剑指offer中提供的时间复杂度是O(m+n),如果考虑将线性二分查找的思想用在矩阵二分查找中,速度可能会有提升。
假设查找17,第一次比较10,然后比较25,然后比较13,返回元素13,这时候再递归查找13左下角的矩阵和右上角的矩阵就可以了(红色椭圆部分);如果是查找9,第一次比较10,然后比较4,然后比较6,返回元素6,这时候递归查找6左下角的矩阵和右上角矩阵(绿色椭圆部分)。
1 int binsearch(int value, int *a, int n, int m1, int n1, int m2, int n2) 2 { 3 int begin_m1 = m1, begin_n1 = n1, end_m2 = m2, end_n2 = n2; 4 int left_result = 0, right_result = 0; 5 int i = (m1+m2)/2, j = (n1+n2)/2; 6 if (a == NULL) 7 return 0; 8 if (value < *(a+m1*n+n1) || value > *(a+m2*n+n2)) 9 return 0; 10 else if (value == *(a+m1*n+n1) || value == *(a+m2*n+n2)) 11 return 1; 12 13 while ((i!=m1 || j!=n1) && (i!=m2 || j!=n2)){ 14 if ( value == *(a+i*n+j) ) 15 return 1; 16 else if ( value < *(a+i*n+j) ){ 17 m2 = i; 18 n2 = j; 19 i = (i+m1)/2; 20 j = (j+n1)/2; 21 } 22 else{ 23 m1 = i; 24 n1 = j; 25 i = (i+m2)/2; 26 j = (j+n2)/2; 27 } 28 } 29 30 //search left & right 31 if ( i<end_m2 ) 32 left_result = binsearch(value, a, n, i+1, begin_n1, end_m2, j); 33 if ( j<end_n2 ) 34 right_result = binsearch(value, a, n, begin_m1, j+1, i, end_n2); 35 if (left_result | right_result ) 36 return 1; 37 else 38 return 0; 39 }
2、思路:
任意维度子矩阵:如果我们将连续k行的元素纵向相加,并对相加后所得的数列求连续最大和,则此连续最大和就是一个行数为k的最优子矩阵!
1 #include <iostream> 2 3 int RowSum(int matrix[][5], int m, int n, int col) 4 { 5 int total = 0, k; 6 for (k = m; k <= n; k++) 7 total += matrix[k][col]; 8 return total; 9 } 10 11 int MaxMatrixSum(int matrix[][5], int rows, int cols) 12 { 13 int maxSum = 0x80000000; 14 int curSum, rowSum; 15 int ele, i, j, col; 16 17 for (i = 0; i < rows; i++) 18 { 19 for (j = i; j < rows; j++) 20 { 21 curSum = RowSum(matrix, i, j, 0); 22 rowSum = RowSum(matrix, i, j, 0); 23 for (col = 1; col < cols; col++) 24 { 25 ele = RowSum(matrix, i, j, col); 26 if (curSum < 0) 27 curSum = ele; 28 else 29 curSum += ele; 30 if (curSum > rowSum) 31 rowSum = curSum; 32 } 33 if (rowSum > maxSum) 34 maxSum = rowSum; 35 } 36 } 37 return maxSum; 38 } 39 40 int main() 41 { 42 int matrix[][5] = {{1, -2, 0, 3, -4}, {2, -3, 4, -5, 1}, {1, -1, 5, 3, 0}}; 43 int result = MaxMatrixSum(matrix, 3, 5); 44 printf("result: %d", result); 45 }
固定维度子矩阵:
1 int GetMaxMatrix(int** matrix, int& row, int& col) 2 { 3 int rowNum, colNum; 4 5 int sum=-(1<<31), temp = 0; 6 7 for (int i = 0; i < row - 1; i++) 8 { 9 for (int j = 0; j < col - 1; j++) 10 { 11 temp += (matrix[i][j] + matrix[i][j+1]); 12 temp += (matrix[i+1][j] + matrix[i+1][j+1]); 13 14 if (temp > sum) 15 { 16 sum = temp; 17 rowNum = i; 18 colNum = j; 19 } 20 temp = 0; 21 } 22 } 23 row=rowNum; 24 col=colNum; 25 26 return sum; 27 }
3、思路:
方阵请参考:http://blog.csdn.net/friendan/article/details/8821591
1 void Transpose(int arr[ROW][COL]) 2 { 3 int temp; 4 for (int i=0;i<ROW;i++) 5 { 6 for(int j=i;j<COL;j++) 7 { 8 temp=arr[i][j]; 9 arr[i][j]=arr[j][i]; 10 arr[j][i]=temp; 11 } 12 } 13 }
矩阵请参考:http://www.qushichao.com/archives/47.html
m×n矩阵用一维数组表示,关键是找到下标数字的移动环。一维数组中的下标移动可以通过二维数组的转置规则求得。
1 void transpose(int *a, int m, int n){ 2 int flag = (m > n) ? n : m; 3 for(int i = 1; i < flag; i++){ 4 int tmp = a[i]; 5 int position = i; 6 while(true){ 7 int row = position / m; 8 int column = position % m; 9 int posToMove = column * n + row; 10 if(posToMove == i){ 11 a[position] = tmp; 12 break; 13 } 14 15 a[position] = a[posToMove]; 16 position = posToMove; 17 } 18 } 19 }