[C语言刷题]杨氏矩阵、返回型参数

news2024/11/23 0:26:54

本文包含知识点

  • 杨氏矩阵极其解法
  • 函数return多个值的四种方法

题目:
杨氏矩阵
有一个数字矩阵,矩阵的每行从左到右是递增的,矩阵从上到下是递增的,请编写程序在这样的矩阵中查找某个数字是否存在。
要求:时间复杂度小于O(N);

  • 一、解题思路
  • 二、代码
    • 2.1第一版——一股脑写在main函数内
    • 2.2第二版——初步封装成函数
    • 2.3第三版——返回型参数(函数内做到return多个值)

一、解题思路

首先我们要清楚什么是杨氏矩阵,题目中也解释得很清楚了,我们看样例
这样的数组有重复元素是允许的,因为题目文的是某个值是否存在,我们只要能找到存在即可,存在多个值没有影响

在这里插入图片描述

再看要求,时间复杂度要小于O(N),这是什么意思,我相信学过算法的朋友都是一眼便知的。如果你还没有学过,那我就用通俗的话解释一下啊,就是该题不允许我们用二层循环遍历的去寻找某个值,我们要用一种效率比二层循环更高的解法来完成

那这里我们该如何解决呢?
emmmm
我们先联想一下以前学过的二分法查找某个数,这个方法的时间复杂度就是小于O(N)。只不过它针对的是有序的一维数组,这里的杨氏数组是每行每列有序的二维数组
(ps:为什么是小于O(N),就是因为二分法每次判断都会减少一半不满足条件的元素,而不是从小到大一个个的循环求解)

思考片刻之后是不是有点思路了!
接下来我就详细讲讲思路:
    如果我们寻找4是否存在在这个数组中
    首先,我们拿右上角的3和4相比,我们发现3比4小,那么我们把这一整行去掉,为什么?因为每行是递增的,如果这一行最右边的3都比4小了,那么这一行都是比3小的元素,怎么可能存在4
    此时矩阵只有第二行和第三行了,然后我们再看矩阵右上角的6,6比4大,那么我们可以把这一整列去掉,为什么呢,因为列从上往下递增,此时的6是该列最小的值了,最小的6都比4大,那么这一列是不可能存在4了
    就这样一直走下去,直到矩阵的最左下角位置,如果还没有发现4,就说明不存在,反之,则存在
好,接下来看看代码

二、代码

2.1第一版——一股脑写在main函数内

#include<stdio.h>

int main()
{
	int arr[3][3] = { 1,2,3,4,5,6,5,7,8 };
	int key = 0;//要寻找的值
	scanf("%d", &key);

	int x = 0;
	int y = 2;//(x,y)是初始矩阵右上角元素的下标
	int flag = 0;
	while (x <= 2 && y >= 0)
	{
		if (arr[x][y] > key)
		{
			y--;//去掉一列
		}
		else if(arr[x][y] < key)
		{
			x++;//去掉一行
		}
		else
		{
			printf("找到了,下标是:(%d,%d)\n", x, y);
			flag = 1;
			break;
		}
	}
	if (0 == flag)
	{
		printf("找不到\n");
	}
	return 0;
}

第一版只能说完成了题目的要求,但我们作为新时代程序猿,对自己的要求要逐步提高,接下来看第二版

2.2第二版——初步封装成函数

这一步其实很简单,把核心功能代码放入函数即可,但是不要心急,这一版是在为第三版做铺垫

#include<stdio.h>

void Young_matrix(int arr[3][3], int key, int row, int col)
{
	int x = 0;
	int y = col-1;//(x,y)是初始矩阵右上角元素的下标
	int flag = 0;
	while (x <= row-1 && y >= 0)
	{
		if (arr[x][y] > key)
		{
			y--;//去掉一列
		}
		else if (arr[x][y] < key)
		{
			x++;//去掉一行
		}
		else
		{
			printf("找到了,下标是:(%d,%d)\n", x, y);
			flag = 1;
			break;
		}
	}
	if (0 == flag)
	{
		printf("找不到\n");
	}

}

int main()
{
	int arr[3][3] = { 1,2,3,4,5,6,5,7,8 };
	int key = 0;//要寻找的值
	scanf("%d", &key);
	Young_matrix(arr, key, 3, 3);

	return 0;
}

这样简单粗暴的封装成函数其实是违背函数高内聚低耦合的原则的,这个打印的需求应该交还给用户,函数内最好只负责找到该数的下标,或者返回特定值告诉用户不存在
但是问题又来了,就是如何在函数里返回两个值呢?思考片刻,我们第三版见

2.3第三版——返回型参数(函数内做到return多个值)

首先,我之前写的文章里以及介绍过三种方式能在函数中return多个值,感兴趣的同学可以戳下方链接去看看
一个函数如何实现return好几个返回值

接下来我们介绍第四种方法,就是返回型参数
    这个方法的思想就是,在函数参数中多传入两个变量的地址,然后在函数中解引用访问这两个变量,可以把需要返回的值放入这两个变量,因为是传址,因此可以成功接收到。
    但是,如果这两个参数是毫无意义的,那我觉得不如就用我之前介绍的三种方式。
    但是但是,在杨氏矩阵这道题里面,我们可以让这两个变量具有意义,这就是为什么我会在这篇文章介绍这个方法的原因了
废话不多说,先看代码,然后再介绍这个方法的妙处

#include<stdio.h>

void Young_matrix(int arr[3][3], int key, int *px, int *py)
{
	int x = 0;
	int y = *py-1;//(x,y)是初始矩阵右上角元素的下标
	while (x <= *px-1 && y >= 0)
	{
		if (arr[x][y] > key)
		{
			y--;//去掉一列
		}
		else if (arr[x][y] < key)
		{
			x++;//去掉一行
		}
		else
		{
			*px = x;
			*py = y;
			return;
		}
	}
	*px = -1;
	*py = -1;
}

int main()
{
	int arr[3][3] = { 1,2,3,4,5,6,5,7,8 };
	int key = 0;//要寻找的值
	scanf("%d", &key);
	int row = 3;
	int col = 3;
	Young_matrix(arr, key, &row, &col);

	if(-1 == row && -1 == col)
	{
		printf("找不到\n");
	}
	else
	{
		printf("找到了,下标是:(%d,%d)\n", row, col);
	}

	return 0;
}

这个方法,首先就是改进了版本中函数没有满足高内聚低耦合的缺点
其次,我们可以看到函数能够把找到的下标成功返回main函数中
最后,参入的参数是极其有意义的。一、row、col代表矩阵的行列长度,这正是矩阵需要的。二、row、col都有代表下标的属性(意思是行列和下标都是代表位置的变量,用来接收目标下标也是情理之中)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/779504.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

js 在浏览器窗口关闭后还可以不中断网络请求

有个需求&#xff0c;我们需要在用户发送数据过程中&#xff0c;如果用户关闭了网页(包括整个浏览器关闭)&#xff0c;不要中断数据传递 目前XMLHttpRequest对象是不支持的 http服务器 为了测试效果我们用nodejs写了个http服务器代码 文件名为httpServer.js如下&#xff0c;…

获取大疆无人机的飞控记录数据并绘制曲线

机型M350RTK&#xff0c;其飞行记录文件为加密的&#xff0c;我的完善代码如下 gitgithub.com:huashu996/DJFlightRecordParsing2TXT.git 一、下载安装官方的DJIFlightRecord git clone gitgithub.com:dji-sdk/FlightRecordParsingLib.git飞行记录文件在打开【我的电脑】&am…

Windows nvm 安装后webstrom vue项目编译报错,无法识别node

1 nvm安装流程 卸载原先nodejs用管理员权限打开exe安装nvmnvm文件夹和nodejs文件夹 都授权Authenticated Users 完全控制nvm list availablenvm install 16.20.1nvm use 16.20.1输入node和npm检查版本命令&#xff0c;正常显示确认系统变量和用户变量都有nvm 和nodejs 2 bug情…

数学建模-聚类算法 系统(层次)聚类

绝对值距离:网状道路 一般用组间和组内距离 聚类的距离计算如何选取&#xff1a;看结果是否解释的通&#xff0c;选择一种结果解释的通的方法。

【数据挖掘】将NLP技术引入到股市分析

一、说明 在交易中实施的机器学习模型通常根据历史股票价格和其他定量数据进行训练&#xff0c;以预测未来的股票价格。但是&#xff0c;自然语言处理&#xff08;NLP&#xff09;使我们能够分析财务文档&#xff0c;例如10-k表格&#xff0c;以预测股票走势。 二、对自然语言处…

【转载+修改】pytorch中backward求梯度方法的具体解析

原则上&#xff0c;pytorch不支持张量对张量的求导&#xff0c;它只支持标量对张量的求导 我们先看标量对张量求导的情况 import torch xtorch.ones(2,2,requires_gradTrue) print(x) print(x.grad_fn)输出&#xff0c;由于x是被直接创建的&#xff0c;也就是说它是一个叶子节…

Vue.js uni-app 混合模式原生App webview与H5的交互

在现代移动应用开发中&#xff0c;原生App与H5页面之间的交互已经成为一个常见的需求。本文将介绍如何在Vue.js框架中实现原生App与H5页面之间的数据传递和方法调用。我们将通过一个简单的示例来展示如何实现这一功能。附完整源码下载地址:https://ext.dcloud.net.cn/plugin?i…

Java集成openAi的ChatGPT实战

效果图&#xff1a; 免费体验地址&#xff1a;AI智能助手 具体实现 public class OpenAiUtils {private static final Log LOG LogFactory.getLog(OpenAiUtils.class);private static OpenAiProxyService openAiProxyService;public OpenAiUtils(OpenAiProxyService openAiP…

【C++】入门 --- 命名空间

文章目录 &#x1f36a;一、前言&#x1f369;1、C简介&#x1f369;2、C关键字 &#x1f36a;二、命名冲突&#x1f36a;三、命名空间&#x1f369;1、命名空间定义&#x1f369;2、命名空间的使用 &#x1f36a;四、C输入&输出 &#x1f36a;一、前言 本篇文章是《C 初阶…

Data Transfer Object-DTO,数据传输对象,前端参数设计多个数据表对象

涉及两张表的两个实体对象 用于在业务逻辑层和持久层&#xff08;数据库访问层&#xff09;之间传输数据。 DTO的主要目的是将多个实体&#xff08;Entity&#xff09;的部分属性或多个实体关联属性封装成一个对象&#xff0c;以便在业务层进行数据传输和处理&#xff0c;从而…

八、HAL_UART(串口)的接收和发送

1、开发环境 (1)Keil MDK: V5.38.0.0 (2)STM32CubeMX: V6.8.1 (3)MCU: STM32F407ZGT6 2、UART和USART的区别 2.1、UART (1)通用异步收发收发器&#xff1a;Universal Asynchronous Receiver/Transmitter)。 2.2、USART (1)通用同步异步收发器&#xff1a;Universal Syn…

【《R4编程入门与数据科学实战》——一本“能在日常生活中使用统计学”的书】

《R 4编程入门与数据科学实战》的两名作者均为从事编程以及教育方面的专家&#xff0c;他们用详尽的语言&#xff0c;以初学者的角度进行知识点的讲解&#xff0c;每个细节都手把手教学,以让读者悉数掌握所有知识点&#xff0c;在每章的结尾都安排理论与实操相结合的习题。与同…

banner轮播图实现、激活状态显示和分类列表渲染、解决路由缓存问题、使用逻辑函数拆分业务(一级分类)【Vue3】

一级分类 - banner轮播图实现 分类轮播图实现 分类轮播图和首页轮播图的区别只有一个&#xff0c;接口参数不同&#xff0c;其余逻辑完成一致 适配接口 export function getBannerAPI (params {}) {// 默认为1 商品为2const { distributionSite 1 } paramsreturn httpIn…

VTK是如何显示一个三维立体图像的

VTK是如何显示一个三维立体图像的 1、文字描述2、图像演示 1、文字描述 2、图像演示

MySQL-事务-介绍与操作

思考 假设在一个场景中&#xff0c;学工部解散了&#xff0c;需要删除该部门及该部门下的员工对应的SQL语句涉及的数据表信息如下 员工表 部门表 实现的SQL语句 -- todo 事务 -- 删除学工部 -- 删除1号部门 delete from tb_dept where id 1; -- 删除学工部下的员工 delete …

SPEC CPU 2006 docker gcc:4 静态编译版本 Ubuntu 22.04 LTS 测试报错Invalid Run

runspec.sh #!/bin/bash source shrc ulimit -s unlimited runspec -c gcc41.cfg -T all -n 1 int fp > runspec.log 2>&1 & tail -f runspec.log runspec.log 由于指定了-T all&#xff0c;导致-n 1 失效&#xff0c;用例运行了三次&#xff08;后续验证&…

【LeetCode 75】 第十题(283)移动零

目录 题目: 示例: 分析: 代码运行结果: 题目: 示例: 分析: 给一个数组,要求将数组中的零都移动到数组的末尾. 首先我们可以遍历一边数组,遇到0的时候就在数组中把0删除,并且统计0的数量. 遍历完成以后数组中就没有0了,这时我们再在数组的后面添上之前统计的0的数量个0. …

IntelliJ IDEA Copyright添加

IDEA代码文件的版权(copyright)信息配置 1. 快速创建Copyright 版权配置文件 1.1 创建copyright文件 依次点击 File > Settings… > Editor > Copyright > 点击 “” 号或 “Add profile”***&#xff0c;弹出创建 Copyright Profile 操作窗口&#xff0c;在***文…

【iOS】App仿写--网易云音乐

文章目录 前言一、首页界面二、我的界面三、账号界面总结 前言 在暑假之前仿写了网易云app&#xff0c;一直没总结。 网易云app主要让我熟悉了视图之间的相互嵌套的用法与关系以及自定义cell的用法&#xff0c;特此撰写以下博客进行总结。 一、首页界面 首先来看一下完成的效…

深度挖掘《TCP与UDP》

文章目录 UDPTCPTCP特性TCP是如何实现的可靠传输&#xff1f;序号和确认序号为啥网络上会后发先至 什么是丢包&#xff0c;如何解决丢包&#xff1f;TCP建立连接&#xff1a;三次握手四次交互&#xff0c;为什叫三次握手&#xff1f;三次握手起到什么效果&#xff1f;达到什么目…