算法工程师重生之第二天(长度最小的子数组 螺旋矩阵II 区间和 开发商购买土地 总结 )

参考文献 代码随想录

一、长度最小的子数组

给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其总和大于等于 target 的长度最小的 

子数组

 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度如果不存在符合条件的子数组,返回 0 。

示例 1:

输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。

示例 2:

输入:target = 4, nums = [1,4,4]
输出:1

示例 3:

输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0

提示:

  • 1 <= target <= 109
  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 105

进阶:

  • 如果你已经实现 O(n) 时间复杂度的解法, 请尝试设计一个 O(n log(n)) 时间复杂度的解法。

暴力

class Solution(object):def minSubArrayLen(self, target, nums):""":type target: int:type nums: List[int]:rtype: int"""# 暴力思路: 2层循环寻找和大于等于target的,然后并计算长度# 定义一个临时变量result存放的是和大于等于target的最小长度result = float('inf')for i in range(len(nums)):  # 先从每一个元素开始找tmpSum = 0 # 临时存放每个长度之和  for j in range(i, len(nums)):  # 找这个元素后面的元素tmpSum += nums[j]if tmpSum >= target:  # 一旦找到,此时必定是当前最小的长度result = min(result, j - i + 1)break  # 调出循环if result == float('inf'):return 0return result

滑动窗口(双指针)

        使用2个指针,一个慢指针(就是更新的值没有另外一个指针快),一个快指针(同理),还需要定义一个变量,接受对应长度的和,result变量统计最小长度之和大于等于target的,然后while循环,那么这个while循环的条件是什么呢?是快指针小于数组的长度,那为什么不判断慢指针呢?因为快指针比慢指针更快到达数组的长度,在while循环,统计和,然后判断此时的和是否大于等于target,问题来了?是使用if呢,还是while呢,这里举一个例子:假设target = 3,数组为[2,3,1,2,4,3],当统计到3,1,2,4的时候,此时是大于target的,那么当满足条件后,移动慢指针时,剩下的还是大于等于target,所以使用while判读,条件成立后,对应的长度=快-慢+1,然后先对和做减法,然后在移动,为什么?因为如果你先移动慢指针,那么在对和做减法的话,就会出错。

class Solution(object):def minSubArrayLen(self, target, nums):""":type target: int:type nums: List[int]:rtype: int"""# 滑动窗口: 双指针寻找和大于等于target的,然后并计算长度,# 定义一个临时变量result存放的是和大于等于target的最小长度result = float('inf')slow = 0fast = 0tmpSum = 0 # 记录临时对应长度的和while fast < len(nums):tmpSum += nums[fast]while tmpSum >= target:  # 为什么要使用while,因为当你移动慢指针的时候,结果还可能大于等于targetresult = min(result, fast - slow + 1)tmpSum -= nums[slow] # 把慢指针向后移,那么这个和就要减去slow += 1fast += 1if result == float('inf'):return 0return result

二、螺旋矩阵 II

给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。

示例 1:

输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]

示例 2:

输入:n = 1
输出:[[1]]

提示:

  • 1 <= n <= 20

思路

总体思路是创建一个 n x n 的矩阵并按螺旋顺序填充数字。步骤如下:(方向的控制,只有遇到超出边界的时候,才调整方向(难点:如何调整方向))

  1. 初始化:创建一个 n x n 的矩阵,所有位置初始化为 0。定义四个方向(右、下、左、上)来控制填充顺序。

  2. 填充逻辑

    • 从矩阵的起始位置(通常是 (0, 0))开始填充数字。
    • 根据当前方向(右、下、左、上)填充下一个位置的数字。
    • 如果遇到矩阵边界或已填充的位置,改变方向。
    • 重复这个过程,直到矩阵完全填充。
  3. 方向控制:使用方向数组和索引来控制填充方向。当无法继续沿当前方向填充时,更新方向索引以切换方向。

这种方法确保了螺旋填充的正确性,逐步向内完成整个矩阵。

class Solution(object):def generateMatrix(self, n):matrix = [[0] * n for _ in range(n)]directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]  # 右、下、左、上x, y = 0, 0direction_index = 0for num in range(1, n * n + 1):  # num代表的是螺旋矩阵的每个元素matrix[x][y] = numnext_x, next_y = x + directions[direction_index][0], y + directions[direction_index][1]  # 向某个方向填充(右、下、左、上)if (0 <= next_x < n and 0 <= next_y < n and matrix[next_x][next_y] == 0):  # 判断边界x, y = next_x, next_yelse:  #如果超过边界,那么就要处理direction_index = (direction_index + 1) % 4  # direction_index 控制方向x += directions[direction_index][0]y += directions[direction_index][1]return matrix

模拟顺时针画矩阵的过程:

  • 填充上行从左到右
  • 填充右列从上到下
  • 填充下行从右到左
  • 填充左列从下到上

由外向内一圈一圈这么画下去。

可以发现这里的边界条件非常多,在一个循环中,如此多的边界条件,如果不按照固定规则来遍历,那就是一进循环深似海,从此offer是路人

这里一圈下来,我们要画每四条边,这四条边怎么画,每画一条边都要坚持一致的左闭右开,或者左开右闭的原则,这样这一圈才能按照统一的规则画下来。

那么我按照左闭右开的原则,来画一圈,大家看一下:

这里每一种颜色,代表一条边,我们遍历的长度,可以看出每一个拐角处的处理规则,拐角处让给新的一条边来继续画。

这也是坚持了每条边左闭右开的原则。

一些同学做这道题目之所以一直写不好,代码越写越乱。

就是因为在画每一条边的时候,一会左开右闭,一会左闭右闭,一会又来左闭右开,岂能不乱。

代码如下,已经详细注释了每一步的目的,可以看出while循环里判断的情况是很多的,代码里处理的原则也是统一的左闭右开。

class Solution:def generateMatrix(self, n: int) -> List[List[int]]:nums = [[0] * n for _ in range(n)]startx, starty = 0, 0               # 起始点loop, mid = n // 2, n // 2          # 迭代次数、n为奇数时,矩阵的中心点count = 1                           # 计数for offset in range(1, loop + 1) :      # 每循环一层偏移量加1,偏移量从1开始for i in range(starty, n - offset) :    # 从左至右,左闭右开,offset控制的是每次填充的边界nums[startx][i] = countcount += 1  # 向右填,那么对应的行不动for i in range(startx, n - offset) :    # 从上至下nums[i][n - offset] = count # 向下填,那么列不动count += 1for i in range(n - offset, starty, -1) : # 从右至左nums[n - offset][i] = count# 向左填,那么对应的行不动count += 1for i in range(n - offset, startx, -1) : # 从下至上nums[i][starty] = count# 向上填,那么列不动count += 1                startx += 1         # 更新起始点starty += 1if n % 2 != 0 :			# n为奇数时,填充中心点nums[mid][mid] = count return nums

三、区间和

题目描述

给定一个整数数组 Array,请计算该数组在每个指定区间内元素的总和。

输入描述

第一行输入为整数数组 Array 的长度 n,接下来 n 行,每行一个整数,表示数组的元素。随后的输入为需要计算总和的区间下标:a,b (b > = a),直至文件结束。

输出描述

输出每个指定区间内元素的总和。

输入示例
5
1
2
3
4
5
0 1
1 3
输出示例
3
9
提示信息

数据范围:
0 < n <= 100000

问题分析

        每个元素记录之前的和,然后利用对应的下标值相减即可

n = int(input())
li = []
for _ in range(n):if not li:li.append(int(input()))else:li.append(li[-1] + int(input()))
target = []
try:while 1:a, b = map(int, input().split())if a == 0:target.append(li[b])else:target.append(li[b] - li[a - 1])
except:pass
for i in target:print(i)

四、开发商购买土地

题目描述

在一个城市区域内,被划分成了n * m个连续的区块,每个区块都拥有不同的权值,代表着其土地价值。目前,有两家开发公司,A 公司和 B 公司,希望购买这个城市区域的土地。 

现在,需要将这个城市区域的所有区块分配给 A 公司和 B 公司。

然而,由于城市规划的限制,只允许将区域按横向或纵向划分成两个子区域,而且每个子区域都必须包含一个或多个区块。 为了确保公平竞争,你需要找到一种分配方式,使得 A 公司和 B 公司各自的子区域内的土地总价值之差最小。 

注意:区块不可再分。

输入描述

第一行输入两个正整数,代表 n 和 m。 

接下来的 n 行,每行输出 m 个正整数。

输出描述

请输出一个整数,代表两个子区域内土地总价值之间的最小差距。

输入示例
3 3
1 2 3
2 1 3
1 2 3
输出示例
0
提示信息

如果将区域按照如下方式划分:

1 2 | 3
2 1 | 3
1 2 | 3 

两个子区域内土地总价值之间的最小差距可以达到 0。

数据范围:

1 <= n, m <= 100;
n 和 m 不同时为 1。

问题分析

        只能横向或者说是纵向切,那么我们就要算出,横向切,之后的最小值,纵向切,之后的最小,那么就可以了

def main():import sysinput = sys.stdin.readdata = input().split()idx = 0n = int(data[idx])idx += 1m = int(data[idx])idx += 1sum = 0  # 保存总的价值vec = []for i in range(n):row = []for j in range(m):num = int(data[idx])idx += 1row.append(num)sum += numvec.append(row)# 统计横向horizontal = [0] * nfor i in range(n):for j in range(m):horizontal[i] += vec[i][j]# 统计纵向vertical = [0] * mfor j in range(m):for i in range(n):vertical[j] += vec[i][j]result = float('inf')horizontalCut = 0for i in range(n):horizontalCut += horizontal[i] # 切割# sum - 2 * horizontalCut 和 sum - horizontalCut - horizontalCut等价result = min(result, abs(sum - 2 * horizontalCut))verticalCut = 0for j in range(m):verticalCut += vertical[j]result = min(result, abs(sum - 2 * verticalCut))print(result)if __name__ == "__main__":main()

数组总结篇#

数组理论基础

数组是非常基础的数据结构,在面试中,考察数组的题目一般在思维上都不难,主要是考察对代码的掌控能力

也就是说,想法很简单,但实现起来 可能就不是那么回事了。

首先要知道数组在内存中的存储方式,这样才能真正理解数组相关的面试题

数组是存放在连续内存空间上的相同类型数据的集合。

数组可以方便的通过下标索引的方式获取到下标对应的数据。

举一个字符数组的例子,如图所示:

需要两点注意的是

  • 数组下标都是从0开始的。
  • 数组内存空间的地址是连续的

正是因为数组在内存空间的地址是连续的,所以我们在删除或者增添元素的时候,就难免要移动其他元素的地址。

例如删除下标为3的元素,需要对下标为3的元素后面的所有元素都要做移动操作,如图所示:

而且大家如果使用C++的话,要注意vector 和 array的区别,vector的底层实现是array,严格来讲vector是容器,不是数组。

数组的元素是不能删的,只能覆盖。

那么二维数组直接上图,大家应该就知道怎么回事了

那么二维数组在内存的空间地址是连续的么?

我们来举一个Java的例子,例如: int[][] rating = new int[3][4]; , 这个二维数组在内存空间可不是一个 3*4 的连续地址空间

看了下图,就应该明白了:

所以Java的二维数组在内存中不是 3*4 的连续地址空间,而是四条连续的地址空间组成!

#数组的经典题目

在面试中,数组是必考的基础数据结构。

其实数组的题目在思想上一般比较简单的,但是如果想高效,并不容易。

我们之前一共讲解了四道经典数组题目,每一道题目都代表一个类型,一种思想。

#二分法

数组:每次遇到二分法,都是一看就会,一写就废(opens new window)

这道题目呢,考察数组的基本操作,思路很简单,但是通过率在简单题里并不高,不要轻敌。

可以使用暴力解法,通过这道题目,如果追求更优的算法,建议试一试用二分法,来解决这道题目

  • 暴力解法时间复杂度:O(n)
  • 二分法时间复杂度:O(logn)

在这道题目中我们讲到了循环不变量原则,只有在循环中坚持对区间的定义,才能清楚的把握循环中的各种细节。

二分法是算法面试中的常考题,建议通过这道题目,锻炼自己手撕二分的能力

#双指针法

  • 数组:就移除个元素很难么?(opens new window)

双指针法(快慢指针法):通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。

  • 暴力解法时间复杂度:O(n^2)
  • 双指针时间复杂度:O(n)

这道题目迷惑了不少同学,纠结于数组中的元素为什么不能删除,主要是因为以下两点:

  • 数组在内存中是连续的地址空间,不能释放单一元素,如果要释放,就是全释放(程序运行结束,回收内存栈空间)。
  • C++中vector和array的区别一定要弄清楚,vector的底层实现是array,封装后使用更友好。

双指针法(快慢指针法)在数组和链表的操作中是非常常见的,很多考察数组和链表操作的面试题,都使用双指针法。

#滑动窗口

  • 数组:滑动窗口拯救了你(opens new window)

本题介绍了数组操作中的另一个重要思想:滑动窗口。

  • 暴力解法时间复杂度:O(n^2)
  • 滑动窗口时间复杂度:O(n)

本题中,主要要理解滑动窗口如何移动 窗口起始位置,达到动态更新窗口大小的,从而得出长度最小的符合条件的长度。

滑动窗口的精妙之处在于根据当前子序列和大小的情况,不断调节子序列的起始位置。从而将O(n^2)的暴力解法降为O(n)。

如果没有接触过这一类的方法,很难想到类似的解题思路,滑动窗口方法还是很巧妙的。

#模拟行为

  • 数组:这个循环可以转懵很多人!(opens new window)

模拟类的题目在数组中很常见,不涉及到什么算法,就是单纯的模拟,十分考察大家对代码的掌控能力。

在这道题目中,我们再一次介绍到了循环不变量原则,其实这也是写程序中的重要原则。

相信大家有遇到过这种情况: 感觉题目的边界调节超多,一波接着一波的判断,找边界,拆了东墙补西墙,好不容易运行通过了,代码写的十分冗余,毫无章法,其实真正解决题目的代码都是简洁的,或者有原则性的,大家可以在这道题目中体会到这一点。

#前缀和

代码随想录后续补充题目

  • 数组:求取区间和(opens new window)

前缀和的思路其实很简单,但非常实用,如果没接触过的录友,也很难想到这个解法维度,所以 这是开阔思路 而难度又不高的好题。

#总结

这个图是 代码随想录知识星球 (opens new window)成员:海螺人 (opens new window),所画,总结的非常好,分享给大家。

从二分法到双指针,从滑动窗口到螺旋矩阵,相信如果大家真的认真做了「代码随想录」每日推荐的题目,定会有所收获。

推荐的题目即使大家之前做过了,再读一遍文章,也会帮助你提炼出解题的精髓所在。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

全网最适合入门的面向对象编程教程:46 Python函数方法与接口-函数与事件驱动框架

全网最适合入门的面向对象编程教程&#xff1a;46 Python 函数方法与接口-函数与事件驱动框架 摘要&#xff1a; 函数是 Python 中的一等公民,是一种可重用的代码块,用于封装特定的逻辑&#xff1b;事件驱动框架是一种编程模式&#xff0c;它将程序的控制流转移给外部事件,如用…

ssm微信小程序校园失物招领论文源码调试讲解

第二章 开发技术与环境配置 以Java语言为开发工具&#xff0c;利用了当前先进的SSM框架&#xff0c;以MyEclipse10为系统开发工具&#xff0c;MySQL为后台数据库&#xff0c;开发的一个微信小程序校园失物招领。 2.1 Java语言简介 Java是由SUN公司推出&#xff0c;该公司于20…

若依框架使用MyBatis-Plus中的baseMapper的方法报错Invalid bound statement (not found):

Invalid bound statement (not found): com.ruoyi.system.mapper.hc.HcOrderMapper.selectList 解决方法 MybatisSqlSessionFactoryBean sessionFactory new MybatisSqlSessionFactoryBean(); 使用 MybatisSqlSessionFactoryBean 而非 SqlSessionFactoryBean 的原因 MyBatis-…

Elasticsearch数据写入过程

1. 写入请求 当一个写入请求&#xff08;如 Index、Update 或 Delete 请求&#xff09;通过REST API发送到Elasticsearch时&#xff0c;通常包含一个文档的内容&#xff0c;以及该文档的索引和ID。 2. 请求路由 协调节点&#xff1a;首先&#xff0c;请求会到达一个协调节点…

1分钟教你用AI制作美女热舞视频,收益可观,操作简单(附工具及教程资料)

美女跳舞&#xff0c;听着是不是就觉得会很哇塞&#xff1f; 不管是男的女的、老的少的都喜欢看&#xff0c;而且一般美女跳舞的账号涨粉都很快&#xff0c;势头都贼猛。 今天就给大家分享一个很热门的小副业——AI美女跳舞。 更多实操和AI绘画工具&#xff0c;可以扫描下方&…

新能源动力组中预充电路及电阻选型分析

新能源动力组中预充电路及电阻选型分析 1.概述2.预充电路与预充电阻3.预充电阻参数选择4.实例分析 1.概述 最近几年&#xff0c;新能源行业在中国得到迅猛发展。由于其高效、节能、低噪声、无污染等特点&#xff0c;它已成为国内工业发展的新趋势包括汽车和飞机。虽然应用在新…

地瓜直播间 | 基于X5平台智能双目深度算法详解

你是否曾经好奇过&#xff0c;机器是如何像人类一样通过双眼来感知三维世界的&#xff1f;双目深度感知技术&#xff0c;是一种模拟人类双眼视觉的高级技术&#xff0c;通过两个摄像头捕捉同一场景的不同视角&#xff0c;深度学习算法能够计算出物体的深度信息&#xff0c;从而…

PX4软/硬件(SITL/HITL)在环仿真

文章目录 介绍依赖PX4 Firmware&#xff1a; 软件在环(SITL)仿真Gazebo 软件无人机STIL连接简要示意SITL SLAM仿真总结示例 HITL 仿真 pxh常用命令MAVLink 指令使用这些命令时的注意事项 参考链接 介绍 为https://blog.csdn.net/weixin_41469272/article/details/117919845的补…

东南亚电商新蓝海:深度解析东南亚服务器租用的战略价值

在全球化日益加深的今天&#xff0c;东南亚以其独特的市场潜力和对数字化技术的积极拥抱&#xff0c;成为了跨境电商及互联网企业竞相角逐的热土。随着东南亚地区经济的快速增长和人口红利的持续释放&#xff0c;电商市场的繁荣景象尤为引人注目。然而&#xff0c;要在这一竞争…

【Linux系统编程】TCP实现--socket

使用套接字socket实现服务器和客户端之间的TCP通信。 流程如下&#xff1a; 实现代码&#xff1a; /* server.c */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <arpa/inet.h> #include <s…

【C++笔记】类和对象的深入理解(一)

【C笔记】类和对象的深入理解(一) &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;C笔记 文章目录 【C笔记】类和对象的深入理解(一)前言一.类的定义1.1类定义格式1.2访问限定符1.3类域 二.实例化2.1 实例化概念2.2对象大小 三.this指针四.练…

[A-09]ARMv8/ARMv9-Memory-内存空间(Address Spaces and Translation Regimes)

ver 0.2 更多精彩内容&#xff0c;请关注公众号 前言 任何人和组织的发展都需要空间&#xff0c;比如我们这个伟大的国家&#xff0c;幅员辽阔、大好河山决定了我们的发展潜力。这么大国土空间&#xff0c;不是随意无须的在发展&#xff0c;都是处于主动的规划(有形的手)或者…

【计网】计算机网络基础

当自律变成一种本能的习惯&#xff0c; 你就会享受到它的快乐。 --- 村上春树 --- 初识计算机网络 1 初识协议1.1 协议分层1.2 OSI七层模型1.3 TCP / IP协议 2 初识局域网2.1 什么是局域网2.2 MAC地址2.3 局域网通信 3 简单认识IP地址 1 初识协议 1.1 协议分层 首先&#…

基于微信小程序的人才招聘系统设计与实现

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 基于微信小程序JavaSpringBootVueMySQL的人才招聘系统设计与…

C++ 音频

一、采样频率 当前主流的采样频率为22.05KHz、44.1KHz、48KHz 22.05KHz&#xff1a;为FM广播声音品质 44.1KHz&#xff1a;为理论上最高的CD声音品质&#xff08;直播&#xff0c;录像&#xff0c;acc&#xff09; 48KHz&#xff1a;人耳可分辨的最高采样频率 &#xff08;…

AI预测福彩3D采取888=3策略+和值012路或胆码测试9月9日新模型预测第82弹

经过80多期的测试&#xff0c;当然有很多彩友也一直在观察我每天发的预测结果&#xff0c;得到了一个非常有价值的信息&#xff0c;那就是9码定位的命中率非常高&#xff0c;70多期一共只错了8次&#xff0c;这给喜欢打私房菜的朋友提供了极高价值的预测结果~当然了&#xff0c…

基于图神经网络的最大独立集问题的目标分支

文章目录 Abstract1 Introduction2 Related Work分支顶点选择图神经网络Abstract 分支归约方法结合了分支约束原则和归约规则,在处理以前无法管理的现实世界实例方面特别成功。分支策略决定下一个要在哪个顶点上进行分支。最近,最广泛使用的策略是选择最高度的顶点。 在这项…

OpenCV-轮廓特征

文章目录 一、简介1.意义2.类别 二、代码实现1.数据预处理2.计算周长3.绘制外接圆轮廓4.绘制外接矩阵 三、总结 一、简介 1.意义 在OpenCV中&#xff0c;轮廓检测后得到的轮廓不仅是一系列点的集合&#xff0c;还可以进一步分析以提取有用的特征。这些特征包括但不限于轮廓的…

读书记录:谷歌工作法 工作效率提升10倍的57个技巧

​ 前言 我在谷歌工作时留下的最深刻印象是“必须以全世界最快的速度取得成果”这一谷歌特有的强烈的使命感。 为什么日本的企业生产效率低下 过度推迟讨论 过分讨论 过度的交流 改变工作方式方法才是生存之道 在这样的时代&#xff0c;我们不应该害怕“自己的工作消失”&a…

使用rsyslog转发自定义日志到指定服务器

rsyslog简介 rsyslog 是一个高度可配置的、功能强大的系统日志守护进程&#xff0c;广泛用于 UNIX 和 Linux 系统中。它是 syslog 的一个扩展版本&#xff0c;提供了许多额外的功能和改进。能够收集、过滤、存储和转发日志数据。它的灵活性和扩展性使其成为现代 Linux 系统中日…