Files
Learn-Algorithms/9 Algorithms Job Interview/矩阵.md
T
2021-03-18 21:24:06 +08:00

4.4 KiB
Raw Blame History

矩阵在计算机中表示就是二维数组。这部分内容都是有关二维数组和矩阵相关的题目。

二维数组中的查找

在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

int exist_inmatrix(int *matrix,int rows,int cols,int num);

矩阵中最大的二维矩阵

求一个矩阵中最大的二维矩阵(元素和最大).如:

1 2 0 3 4
2 3 4 5 1
1 1 5 3 0

中最大的是:

4 5
5 3

要求:(1)写出算法;(2)分析时间复杂度;(3)用C写出关键代码

int max_sum_submatrix(int *matrix,int rows,int cols,int *tmatrix,int *trows,int tcols)

顺时针打印矩阵

题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。 例如:如果输入如下矩阵:

1              2              3              4
5              6              7              8
9              10             11             12
13             14             15             16

则依次打印出数字1, 2, 3, 4, 8, 12, 16, 15, 14, 13, 9, 5, 6, 7, 11, 10 。

分析:包括Autodesk、EMC在内的多家公司在面试或者笔试里采用过这道题。

一圈一圈打印,第一圈origin是(0,0),第二圈是(1,1)

void print_matrix(int **matrix,int rows,int cols);
//或
void print_matrix(int *matrix,int rows,int cols);

示例代码:

void print_matrix(int *matrix,int rows,int cols){
	if(matrix==NULL) return ;
	if(rows<=0 || cols<=0) return;

	int start = 0;
	while(start*2<cols && start*2<rows){
		print_matrix_incircle(matrix,rows,cols,start);
		start++;
	}
}

// a[i*rows+j]
void print_matrix_incircle(int *matrix,int rows,int cols,int start){
	int endX = cols-start-1;
	int endY = rows-start-1;

	//然后依次打印 上,右,下,左
	for(int i=start;i<=endX,i++){
		printf("\d ",matrix[start*rows+i]);
	}

	for(int i=start+1;i<=endY,i++){
		printf("\d ",matrix[i*rows+endX]);
	}

	for(int i=endX-1;i>=start;i--){
		printf("\d ",matrix[start*rows+i]);
	}

	for(int i=endY-1;i>start;i--){
		printf("\d ",matrix[i*rows+start]);
	}
}

测试代码见 print_matrix.c

从小到大输出矩阵的值

思路1:采用归并进行排序然后进行顺序打印 思路2:用n个指针指向每一行的第一个数,比较n个指针的数,打印最小的,然后指针后移,若无下一位,则赋值为null,直至所有数都对印完毕

void printArry(int *a,int rows,int columns)
{
    if(a==null)
        return;

    int *arr=new int[rows*(columns+1)];//添加看门狗值,INT_MAX
    for(int i=0;i<rows;i++)
        for(int j=0;j<columns+1;j++)
        {
            if(j==columns)
                arr[i*(columns+1)+j]=INT_MAX;
            else
                arr[i*(columns+1)+j]=a[i*columns+j];
        }

    int* pArr1=new int[rows];//共存有这么多行指针
    for(int i=0;i<rows;i++)
        pArr1[i]=i*(columns+1);
    while(1)
    {
        int min=arr[pArr1[0]];
        int mini=0;
        for(int i=0;i<rows;i++)
        {//第i个数组最小
            int index=pArr1[i];
            if(min>arr[index])
            {
                min=arr[index];
                mini=i;
            }
        }
        if(min==INT_MAX)
            break;//表示都达到了看门处,则跳出循环。
        cout<<min<<" ";
        pArr1[mini]++;//指针前移动
    }
}

算法复杂度时O(mn);m是行数,n是列数;对原矩阵,增加一列,用于看门;利用类似归并排序中的整合过程,此处是整合m个有序数列,最后得到有序输出。

n支队伍比赛的名次

n支队伍比赛,分别编号为0,1,2。。。。n-1,已知它们之间的实力对比关系,存储在一个二维数组w[n][n]中,w[i][j] 的值代表编号为i,j的队伍中更强的一支。

所以w[i][j]=i 或者j,现在给出它们的出场顺序,并存储在数组order[n]中, 比如order[n] = {4,3,5,8,1......},那么第一轮比赛就是 4对3, 5对8。.......

胜者晋级,败者淘汰,同一轮淘汰的所有队伍排名不再细分,即可以随便排,下一轮由上一轮的胜者按照顺序,再依次两两比,比如可能是4对5,直至出现第一名

编程实现,给出二维数组w,一维数组order 和 用于输出比赛名次的数组result[n],求出result。