目录:
一、顺序打印矩阵(n*m)
二、二维数组中的查找
三、大数相加
四、合并两个有序数组
一、顺序打印矩阵(n*m)
题目:在n*m的矩阵中,我们按照顺时针将矩阵打印出来,下面有几种情况:4*4、4*3 、4*2、3*4、我们将他们打印的图示画出来:
下面我们将代码进行演示:
void Array(int(*arr)[4], int row, int col) { assert(arr != NULL); int start = 0; while (start < row / 2 && start < col / 2) { //控制圈数 int endX = col - 1 - start; //打印当前圈数的最后一列 int endY = row - 1 - start; //打印当前圈数的最后一行 //从左往右打印 for (int i = start; i <= endX; i++) { printf("%5d", arr[start][i]); } //从上往下打印 if (start < endY) { for (int i = start + 1; i <= endY; i++) { printf("%5d", arr[i][endX]); } } //从右往左打印 if (start < endY && start < endX) { for (int i = endX - 1; i >= start; i--) { printf("%5d", arr[endY][i]); } } //从下往上打印 if (start < endX && start < endY - 1) { for (int i = endY - 1; i >= start + 1; i--) { printf("%5d", arr[i][start]); } } start++; } } int main() { int arr[4][4] = { { 1,2,3,4 }, { 5,6,7,8 }, { 9,10,11,12 }, { 13,14,15,16 } }; Array(arr, 4, 4); return 0; }
运行结果:
1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10 D:\c程序\p2-1\Debug\p2-1.exe (进程 11992)已退出,代码为 0。 要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。 按任意键关闭此窗口. . .
二、二维数组中的查找
题目:在一个二维数组array中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序在排序,请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
我们将图示画出来:
代码如下:
int research(int(*arr)[4],int row,int col,int index) { assert(arr!= NULL); int x = 0; int y = col - 1; while (x <row &&y>=0) { //时间复杂度为o(m+n),空间复杂度为o(1) if (index == arr[x][y]) { return index; } else if (index < arr[x][y]) { y--; } else { x++; } } return -1; } int main() { int arr[4][4] = { {1,2,3,4},{6,7,8,9},{11,12,13,14},{16,17,18,19} }; int res=research(arr, 4, 4, 18); printf("%d", res); }
运行结果:
18 D:\c程序\p2-1\Debug\p2-1.exe (进程 16660)已退出,代码为 0。 要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。 按任意键关闭此窗口. . .
三、大数相加
题目:以字符串的形式读入两个数字,编写一个函数计算他们的和,以字符串的形式返回,字符串仅由'0'~'9'构成,要求时间复杂度为o(n)。
原理:当我们拿到这道题目的时候,我们根据题意可知,首先以字符串的形式读入两个数,计算两个数的和,这里涉及到了字符转数字,而相加涉及到了本位和进位的关系,最后以字符串的形式返回,又涉及到了数字转字符
char* getsum(const char* arr,const char *arr1,char *result) { assert(arr != NULL && arr1 != NULL); int endarr = strlen(arr)-1; //从最后一位开始相加 int endarr1 = strlen(arr1)-1; int sum = 0; //记录求和结果 int carry = 0; //记录进位 int n1, n2; int count = 0; while (endarr >= 0 || endarr1 >= 0) { //字符转数字 n1 = endarr >= 0 ? arr[endarr--] - '0' : 0; n2 = endarr1 >= 0 ? arr1[endarr1--] - '0' : 0; sum = n1 + n2+carry; if (sum >= 10) { carry = 1; result[count++] = sum % 10 + '0'; //数字转字符 } else { carry = 0; result[count++] = sum + '0'; } } result[count] = '\0'; //数组逆转 int j = count-1; for (int i = 0; i < j; i++) { int temp = result[i]; result[i] = result[j]; result[j] = temp; j--; } return result; } int main() { const char* arr = "123"; const char* arr1 = "9"; char res[100]; getsum(arr, arr1, res); printf("%s", res); }
四、合并两个有序数组
题目:合并两个有序数组,例如:arr:1 2 3 5 7、(长度足够大)brr:1 2 2 4 8 9 10。将两个数组合并使时间复杂度变为最小
//第一种方式插入数据,时间复杂度O(m*n),时间复杂度高
//第二种方法归并算法,额外开辟空间,谁小谁下来,时间复杂度O(nlogn)
//第三种方法,排序,时间复杂度O(n^2)
//第四种方法,从后往前遍历,谁大谁往后走,时间复杂度O(m+n)这里我们用第四种方法进行代码的编写
void array(int* arr, int* brr,int m,int n) { int i = m - 1; //arr有效长度 int j = n - 1; //brr有效长度 int z = m + n-1; //arr总长度的末端 while (i >= 0 && j >= 0) { arr[z--] = arr[i] > brr[j] ? arr[i--]:brr[j--]; //谁大谁往后走 } while (j >= 0) { //j没有走完,i走完,要将j剩下的数据向上进行移动 arr[z--] = brr[j--]; } } int main() { int arr[30] = {1,2,3,5,7}; int brr[] = {1,2,2,4,8,9,10}; int n = sizeof(brr) / sizeof(brr[0]); array(arr, brr, 5, n); for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) { printf("%5d", arr[i]); } }
本文含有隐藏内容,请 开通VIP 后查看