【算法题】螺旋矩阵I (求解n阶螺旋矩阵问题)

news2024/12/22 22:38:08

一、问题的提出

螺旋矩阵是一种常见的矩阵形式,它的特点是按照螺旋的方式排列元素。n阶螺旋矩阵是指矩阵的大小为n×n,其中n为正整数。

 二、解决的思路

当N=1时,矩阵为\left ( 1 \right );

当N=2时,矩阵为\begin{pmatrix} 1&2\\ 4&3 \end{pmatrix};

当N>2(N为偶数如N=4)时,矩阵为\begin{pmatrix} 1&2&3&4\\ 12&13&14&5\\ 11&16&15&6\\ 10&9&8&7 \end{pmatrix};


当N>2(N为奇数如N=5)时,矩阵为\begin{pmatrix} 1&2&3&4&5\\ 16&17&18&19&6\\ 15&24&25&20&7\\ 14&23&22&21&8\\ 13&12&11&10&9 \end{pmatrix}

图1 螺旋矩阵分析图

三、递推法解题

从上思路分析和图1可知,当N>2时可分为k(k=N//2)个四边形的螺旋框,每边长为框长度(n)-1(即n-1),只是左上角的起始值和边框长度不同而已。如N为奇数,则正中心还有一个终值N²。

因此可用用递推来计算。

程序代码如下:

N = 5
def prt(b):                           # 打印二维列表
    for i in range(N):
        for j in range(N):
            print("%3d" % b[i][j], end='')
        print()

def Helix_Matrix(N):
    matrix = []                       # 初始化二维矩阵matrix(二维列表)
    for i in range(N):
        matrix.append([])
        for j in range(N):
            matrix[i].append(0)
    matrix[N//2][N//2] = N*N          # 若N为奇数时,正中间为N²
    cnt = 0
    n = N
    for k in range(N//2):
        for j in range(n-1):          # 矩形上边,从左向右
            cnt += 1
            matrix[k][k+j] = cnt
        for i in range(n-1):          # 矩形右边,从上往下
            cnt += 1
            matrix[k+i][k+n-1] = cnt
        for j in range(n-1):          # 矩形下边,从右向左
            cnt += 1
            matrix[k+n-1][k+n-1-j] = cnt
        for i in range(n-1):          # 矩形左边,从下往上
            cnt += 1
            matrix[k+n-1-i][k] = cnt
        n -= 2                        # 缩小规模时,矩形边长减2
    return matrix

hm = Helix_Matrix(N)
prt(hm)

执行结果:

12345
161718196
152425207
142322218
131211109

回到开头的题目,则

def Helix_Matrix(N):
    matrix = []                    # 初始化二维矩阵matrix(二维列表)
    for i in range(N):
        matrix.append([])
        for j in range(N):
            matrix[i].append(0)
    matrix[N//2][N//2] = N*N       # 若N为奇数时,正中间为N²
    cnt = 0
    n = N
    for k in range(N//2):
        for j in range(n-1):       # 矩形上边,从左向右
            cnt += 1
            matrix[k][k+j] = cnt
        for i in range(n-1):       # 矩形右边,从上往下
            cnt += 1
            matrix[k+i][k+n-1] = cnt
        for j in range(n-1):       # 矩形下边,从右向左
            cnt += 1
            matrix[k+n-1][k+n-1-j] = cnt
        for i in range(n-1):       # 矩形左边,从下往上
            cnt += 1
            matrix[k+n-1-i][k] = cnt
        n -= 2                     # 缩小规模时,矩形边长减2
    return matrix

n, i, j = map(int,input().split())
hm = Helix_Matrix(n)
print(hm[i-1][j-1])

输入4 2 3,输出为14。

四、递归法解题

当规模为1时直接填写(1个元素),见“二、解决的思路,结束递归;

当规模为2时直接填写(4个元素),见“二、解决的思路,结束递归;

当规模大于2时直接先写本圈(k)四边,见“二、解决的思路,再缩小规模递归调用。

这就是递归计算算法。

程序代码如下:

N = 6
def prt(b):                           # 打印二维列表
    for i in range(N):
        for j in range(N):
            print("%3d" % b[i][j], end='')
        print()

def Helix_Matrix(n,k,cnt):
    if n == 1:                        # 规模为1
        matrix[k][k] = cnt
    elif n == 2:                      # 规模为2
        matrix[k][k] = cnt
        cnt += 1
        matrix[k][k+1] = cnt
        cnt += 1
        matrix[k+1][k+1] = cnt
        cnt += 1
        matrix[k+1][k] = cnt
    else:                             # 规模大于2
        for j in range(n-1):          # 矩形上边,由左向右
            matrix[k][k+j] = cnt
            cnt += 1
        for i in range(n-1):          # 矩形右边,由上往下
            matrix[k+i][k+n-1] = cnt
            cnt += 1
        for j in range(n-1):          # 矩形下边,由右向左
            matrix[k+n-1][k+n-1-j] = cnt
            cnt += 1
        for i in range(n-1):          # 矩形左边,由下往上
            matrix[k+n-1-i][k] = cnt
            cnt += 1
        Helix_Matrix(n-2, k + 1, cnt) # 递归,缩小螺旋矩阵规模

matrix = []                           # 初始化二维矩阵matrix(二维列表)
for i in range(N):
    matrix.append([])
    for j in range(N):
        matrix[i].append(0)
Helix_Matrix(N,0,1)                   # 初始n=N, k=0, cnt=1
prt(matrix)

执行结果:

123456
20212223247
19323334258
18313635269
173029282710
161514131211

 回到开头的题目,则

def Helix_Matrix(n,k,cnt):
    if n == 1:                       # 规模为1
        matrix[k][k] = cnt
    elif n == 2:                     # 规模为2
        matrix[k][k] = cnt
        cnt += 1
        matrix[k][k+1] = cnt
        cnt += 1
        matrix[k+1][k+1] = cnt
        cnt += 1
        matrix[k+1][k] = cnt
    else:                             # 规模大于2
        for j in range(n-1):          # 矩形上边,由左向右
            matrix[k][k+j] = cnt
            cnt += 1
        for i in range(n-1):          # 矩形右边,由上往下
            matrix[k+i][k+n-1] = cnt
            cnt += 1
        for j in range(n-1):          # 矩形下边,由右向左
            matrix[k+n-1][k+n-1-j] = cnt
            cnt += 1
        for i in range(n-1):          # 矩形左边,由下往上
            matrix[k+n-1-i][k] = cnt
            cnt += 1
        Helix_Matrix(n-2, k + 1, cnt) # 递归,缩小螺旋矩阵规模

N, x, y = map(int,input().split())
matrix = []                           # 初始化二维矩阵matrix(二维列表)
for i in range(N):
    matrix.append([])
    for j in range(N):
        matrix[i].append(0)
Helix_Matrix(N,0,1)                   # 初始n=N, k=0, cnt=1
print(matrix[x-1][y-1])

输入4 2 3,输出为14。

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

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

相关文章

通达OA SQL注入漏洞【CVE-2023-4166】

通达OA SQL注入漏洞【CVE-2023-4166】 一、产品简介二、漏洞概述三、影响范围四、复现环境POC小龙POC检测工具: 五、修复建议 免责声明:请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损…

简单网络-跨网段通信

跨网段通信 1.为PC1,PC2配置IP地址、子网掩码和网关后用PC1 ping PC2,并用wireshark抓包g0/0/2的数据包。结果发现不能ping通,而PC1在发送广播包,寻找10.0.1.254网关,说明PC1找不到网关 2.给路由器e0/0/0端口配置网关1…

git一次错误merge的回滚

场景:提交到sit的代码,结果解决冲突merge了DEV的代码,所以要回滚到合并之前的代码 (原因是我再网页上处理了冲突,他就自动merge了,如图—所以还是idea处理冲突,可控) 方式二: &…

【Java多线程】CompletableFuture 异步多线程

1. 回顾 Future 一些业务场景我们需要使用多线程异步执行任务,加快任务执行速度。 JDK5新增了Future接口,用于描述一个异步计算的结果。 虽然 Future 以及相关使用方法提供了异步执行任务的能力,但是对于结果的获取却是很不方便&#xff0…

docker安装Nacos的《小白专用》详细教程

1.CentOS安装docker 安装docker yum -y install docker 设置开机自启 systemctl enable docker 启动docker systemctl start docker 查看docker当前的版本 docker version做到这里呢基本上你的docker就安装了一大部分了,当然也有那些无法安装的人,那我建…

prometheus监控k8s服务并告警到钉钉

一、监控k8s集群 要监控k8s集群需要使用到以下服务用于收集监控的资源信息,node_exporter用于监控k8s集群节点的资源信息,kube-state-metrics用于监控k8s集群的deployment、statefulset、daemonset、pod等的状态,cadvisor用于监控k8s集群的p…

爆肝整理,Python自动化测试-Pytest参数化实战封装,一篇打通...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 参数化&#xff1…

Gradio:交互式Python数据应用程序的新前沿

一、说明 什么是Gradio以及如何使用Gradio在Python中创建DataApp或Web界面?使用 Gradio 将您的 Python 数据科学项目转换为交互式应用程序。 摄影:Elijah Merrell on Unsplash Gradio是一个Python库,允许我们快速为机器学习模型创建可定制的接…

工程英语翻译怎样做效果比较好

我们知道,高质量的工程翻译可以有效指导工程项目操作的执行,但市场上专业的工程英语翻译人才严重不足。那么,工程英语翻译难吗,怎样翻译工程英语比较好? 业内人士指出, 工程翻译具有用词专业、涉及领域广、…

Python(八十一)字符串的常用操作——字符串判断的相关方法

❤️ 专栏简介:本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中,我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 :本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

Python3 安装、环境变量配置、PyCharm新建Python项目

一、安装包下载 Pyhton官网下载>>最新稳定版的安装包: 找到合适的版本进行下载: 如果下载较慢,此处提供一个3.10.11的稳定版本的安装包: 链接:https://pan.baidu.com/s/16GnWjkGFuSfWfaI9UVX8qA?pwd4u5o 提取…

案例13 Spring MVC参数传递案例

基于Spring MVC实现HttpServletRequest、基本数据类型、Java Bean、数组、List、Map、JSON方式的参数传递。 1. 创建项目 选择Maven快速构建web项目&#xff0c;项目名称为case13-springmvc02。 2. 配置Maven依赖 <?xml version"1.0" encoding"UTF-8&quo…

【JavaScript】怎么测试方法的兼容性

利用网站测试方法的兼容性 打开网站&#xff1a;https://caniuse.com在里面输入要检测的方法&#xff0c;红色代表不支持&#xff0c;绿色代码支持。

Linux:Shell编程之正则表达式

目录 绪论 1、正则表达式 1.1 通配符 1.2 正则表达式分类 1.3 基本正则 1.4 正则表达式中表示次数的表达式 1.5 位置锚定 1.5.1 词首锚定和词尾锚定 1.6 分组&#xff08;&#xff09; 1.7 逻辑或 1.8 扩展正则 绪论 正则表达式&#xff1a;有一类特殊字符以及文本…

10-1_Qt 5.9 C++开发指南_Data Visualization实现数据三维显示

Data Visualization 是 Qt 提供的用于数据三维显示的模块。在 Qt 5.7 以前只有商业版才有此模块&#xff0c;而从Qt5.7 开始此模块在社区版本里也可以免费使用了。Data Visualization 用于数据的三维显示&#xff0c;包括三维柱状图、三维空间散点、三维曲面等。Data Visualiza…

【教程】初识云函数,实现无需服务器的项目上云!

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhang.cn] 你是否也在忧愁&#xff0c;想把自己的项目放在云上跑&#xff0c;但又不想花大价钱购买云服务器&#xff1f; 云函数介绍 云函数(Serverless Cloud Function&#xff0c;SCF)的简单理解就是&#xff1a;可以部署…

第四十八周周报

学习目标&#xff1a; 修改ViTGAN 学习内容&#xff1a; 位置编码和多尺度 学习时间&#xff1a; 8.5-8。12 学习产出&#xff1a; 这两周主要工作在修改ViTGAN的结构和代码&#xff0c;将相对位置编码加入ViTGAN并将生成器变为多尺度&#xff0c;由于匹配维度很困难&am…

国产航顺HK32F030M: 内部参考电压

HK32F030MF4P6 用户手册 内部参考电压 adc.c #include "bsp_adc.h"/*** brief ADC GPIO 初始化* param 无* retval 无*/ static void ADCx_GPIO_Config(void) {GPIO_InitTypeDef GPIO_InitStructure;// 打开 ADC IO端口时钟ADC_GPIO_AHBxClock_FUN ( ADC_GPIO_C…

无涯教程-Perl - msgctl函数

描述 该函数使用参数ID,CMD和ARG调用系统函数msgctrl()。您可能需要包括IPC::SysV包以获得正确的常量。 语法 以下是此函数的简单语法- msgctl ID, CMD, ARG返回值 该函数返回0,但如果系统函数成功返回0和1,则返回true。 Perl 中的 msgctl函数 - 无涯教程网无涯教程网提供…

TCP协议的报头格式和滑动窗口

文章目录 TCP报头格式端口号序号和确认序号确认应答&#xff08;ACK&#xff09;机制超时重传机制 首部长度窗口大小报文类型URGACKSYNPSHFINRST 滑动窗口滑动窗口的大小怎么设定怎么变化滑动窗口变化问题 TCP报头格式 端口号 两个端口号比较好理解&#xff0c;通过端口号来找…