当前位置: 首页 > news >正文

算法归纳【数组篇】

目录

  • 二分查找
    • 1. 前提条件:
    • 2. 二分查找边界
  • 2.移除元素
  • 有序数组的平方
  • 长度最小的子数组
  • 59.螺旋矩阵II
    • 54. 螺旋矩阵

二分查找

参考链接
https://programmercarl.com/0704.%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE.html#%E6%80%9D%E8%B7%AF

1. 前提条件:

  1. 数组为有序数组,
  2. 无重复元素:因为一旦有重复元素,使用二分查找法返回的元素下标可能不是唯一的。

2. 二分查找边界

  1. [left, right]区间:while (left <= right) 要使用 <= ,因为left == right是有意义的,所以使用 <=
    if (nums[middle] > target) right 要赋值为 middle - 1
    ,因为当前这个nums[middle]一定不是target,那么接下来要查找的左区间结束下标位置就是 middle - 1
func search(nums []int, target int) int {high := len(nums)-1low := 0for low <= high {mid := low + (high-low)/2if nums[mid] == target {return mid} else if nums[mid] > target {high = mid-1} else {low = mid+1}}return -1
}
  1. 区间[left, right):while (left < right),这里使用 < ,因为left == right在是没有意义的
    if (nums[middle] > target) right 更新为 middle
    ,因为当前nums[middle]不等于target,去左区间继续寻找,而寻找区间是左闭右开区间,所以right更新为middle,即:下一个查询区间不会去比较nums[middle]
func search(nums []int, target int) int {high := len(nums)low := 0for low < high {mid := low + (high-low)/2if nums[mid] == target {return mid} else if nums[mid] > target {high = mid} else {low = mid+1}}return -1
}

====================================================================

2.移除元素

参考链接
https://programmercarl.com/0027.%E7%A7%BB%E9%99%A4%E5%85%83%E7%B4%A0.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE

数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖。 所以不可以删除,只能将等于val的值移到后面,最后的结果返回数组满足条件的前半部分即可

func removeElement(nums []int, val int) int {left, right := 0, len(nums)-1for left <= right {if nums[left] == val {nums[left] = nums[right]right--} else {left++}}return left
}

顺便从二分法学以致用:【关于 left <= right 和 left < right 的选择问题】

func removeElement(nums []int, val int) int {left, right := 0, len(nums)for left < right {if nums[left] == val {nums[left] = nums[right-1]right--} else {left++}}return left
}

=================================================================

有序数组的平方

参考链接
https://programmercarl.com/0977.%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E7%9A%84%E5%B9%B3%E6%96%B9.html#%E5%85%B6%E4%BB%96%E8%AF%AD%E8%A8%80%E7%89%88%E6%9C%AC

双指针法
数组其实是有序的, 只不过负数平方之后可能成为最大数了。
那么数组平方的最大值就在数组的两端,不是最左边就是最右边,不可能是中间。
此时可以考虑双指针法了,i指向起始位置,j指向终止位置。
定义一个新数组result,和A数组一样的大小,让k指向result数组终止位置。
如果A[i] * A[i] < A[j] * A[j] 那么result[k–] = A[j] * A[j]; 。
如果A[i] * A[i] >= A[j] * A[j] 那么result[k–] = A[i] * A[i]; 。

func sortedSquares(nums []int) []int {n := len(nums)i, j, k := 0, n-1, n-1ans := make([]int, n)for i <= j {lm, rm := nums[i]*nums[i], nums[j]*nums[j]if lm > rm {ans[k] = lmi++} else {ans[k] = rmj--}k--}return ans
}

========================================================

长度最小的子数组

参考链接
https://programmercarl.com/0209.%E9%95%BF%E5%BA%A6%E6%9C%80%E5%B0%8F%E7%9A%84%E5%AD%90%E6%95%B0%E7%BB%84.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE

给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。
示例:
输入:s = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。

滑动窗口

func minSubArrayLen(target int, nums []int) int {if len(nums) == 0 {return 0}slow, fast := 0, 0sum := nums[0]minLen := len(nums) + 1for fast < len(nums) {if sum >= target {minLen = min(minLen, fast-slow+1)//还要记住改变sum的值,否则就会带着sum=7这个结果一直循环sum = sum - nums[slow]slow++} else if sum < target {fast++if fast < len(nums) {sum = sum + nums[fast]}} }if minLen == len(nums)+1 {return 0}return minLen
}

=========================================================

59.螺旋矩阵II

给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。
示例:
输入: 3
输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]

参考链接
https://programmercarl.com/0059.%E8%9E%BA%E6%97%8B%E7%9F%A9%E9%98%B5II.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE

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

//左开右闭
func generateMatrix(n int) [][]int {top, bottom := 0, n-1left, right := 0, n-1num := 1tar := n * nmatrix := make([][]int, n)for i := 0; i < n; i++ {matrix[i] = make([]int, n)}for num <= tar {for i := left; i <= right; i++ {matrix[top][i] = numnum++}top++for i := top; i <= bottom; i++ {matrix[i][right] = numnum++}right--for i := right; i >= left; i-- {matrix[bottom][i] = numnum++}bottom--for i := bottom; i >= top; i-- {matrix[i][left] = numnum++}left++}return matrix
}

54. 螺旋矩阵

给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。
在这里插入图片描述
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]

func spiralOrder(matrix [][]int) []int {result := []int{}//矩阵先考虑条件if len(matrix) == 0 || len(matrix[0]) == 0 {return result}m, n := len(matrix), len(matrix[0])left, right, top, bottom := 0, n-1, 0, m-1for left <= right && top <= bottom {// 从左到右for i := left; i <= right; i++ {result = append(result, matrix[top][i])}// 从上到下for i := top + 1; i <= bottom; i++ {result = append(result, matrix[i][right])}// 从右到左,确保有多行// 在螺旋顺时针遍历矩阵的过程中,从右到左的遍历应该在确保存在多行的情况下进行。如果只有一行,那么从右到左的遍历就没有意义,因为在上一步已经从左到右遍历过了。因此,通过 if top < bottom 进行判断,可以确保在有多行的情况下才进行从右到左的遍历。//  比如 6->7的过程,因为经过一轮之后top=1,bottom=1,此时6->7是从左到右,不需要从右到左,下面的left < right同理if top < bottom {for i := right - 1; i >= left; i-- {result = append(result, matrix[bottom][i])}}// 从下到上,确保有多列if left < right {for i := bottom - 1; i > top; i-- {result = append(result, matrix[i][left])}}left++right--top++bottom--}return result
}

相关文章:

算法归纳【数组篇】

目录 二分查找1. 前提条件&#xff1a;2. 二分查找边界 2.移除元素有序数组的平方长度最小的子数组59.螺旋矩阵II54. 螺旋矩阵 二分查找 参考链接 https://programmercarl.com/0704.%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE.html#%E6%80%9D%E8%B7%AF 1. 前提条件&#xff1a; 数…...

【随笔】程序员如何选择职业赛道,目前各个赛道的现状如何,那个赛道前景巨大

大家好&#xff0c;我是全栈小5&#xff0c;欢迎阅读文章&#xff01; 此篇是【话题达人】系列文章&#xff0c;这一次的话题是《程序员如何选择职业赛道》 目录 背景热度柱状图赛道热度C/C云原生人工智能前沿技术软件工程后端JavaJavascriptPHPPython区块链大数据移动开发嵌入…...

进程之舞:操作系统中的启动、状态转换与唤醒艺术

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua&#xff0c;在这里我会分享我的知识和经验。&#x…...

Java面试(4)之 Spring Bean生命周期过程

一, 整个加载的完整链路图 更详细的生命周期函数链路图(仅供参考) 二, Bean实例化的四种方式: 1, 无参构造器(默认且常用)6 2, 静态工厂方法方式(factory-method指定实例化的静态方法) 3, 实例工厂方法方式(factory-bean指定bean的name,factory-method指定实例化方法) 4, 实…...

JavaSE——面向对象高级一(1/4)-static修饰成员变量、应用场景,static修饰成员方法、应用场景

目录 static修饰成员变量 类变量的应用场景 static修饰成员方法 static修饰成员方法的应用场景 static 叫静态&#xff0c;可可以修饰成员变量、成员方法。 成员变量按照有无static修饰&#xff0c;分为两种&#xff1a; 类变量实例变量&#xff08;对象的变量&#xff…...

轻量脚本语言Lua的配置与c++调用

文章目录 lua配置下载运行lua命令lua脚本的执行C++调用lua环境配置错误和警告测试c++程序lua脚本结果Lua是一种功能强大且快速的编程语言,易于学习和使用,并且可以嵌入到应用程序中。 Lua被设计成一种轻量级的可嵌入脚本语言。它被用于各种各样的应用程序,从游戏到web应用程…...

力扣每日一道系列 --- LeetCode 160. 相交链表

&#x1f4f7; 江池俊&#xff1a; 个人主页 &#x1f525;个人专栏&#xff1a; ✅数据结构探索 ✅LeetCode每日一道 &#x1f305; 有航道的人&#xff0c;再渺小也不会迷途。 LeetCode 160. 相交链表 思路&#xff1a; 首先计算两个链表的长度&#xff0c;然后判断两个链…...

设计模式-建造者模式实践案例

建造者模式&#xff08;Builder Pattern&#xff09;是一种创建型设计模式&#xff0c;它提供了一种创建对象的最佳方式。当一个对象需要多个部分或许多步骤来创建&#xff0c;并且需要将创建过程与表示分离时&#xff0c;建造者模式非常有用。建造者模式旨在找到一个解决方案&…...

freeRTOS_20240308

1.使用ADC采样光敏电阻数值&#xff0c;如何根据这个数值调节LED灯亮度。 HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_3); while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */HAL_ADC_Start(&hadc);adc_val HAL_ADC_GetValue(&hadc);printf("adc_va…...

利用chatgpt写论文使用教程

ChatGPT是人工智能技术的一种&#xff0c;可帮助人们综合运用和分析各种语言技巧&#xff0c;从而优化实验结果、加速研究流程以及提高文章质量。以下是利用ChatGPT写论文的使用教程&#xff1a; 综上所述&#xff0c;利用ChatGPT写论文涉及到一些技巧和方法&#xff0c;需要合…...

SMiC矩阵将于3月6日正式上线,开启数字化经济新纪元

在数字化浪潮的推动下&#xff0c;全球瞩目的SMiC矩阵将于2024年3月6日正式上线。这一里程碑式的事件标志着数字化经济迈入了一个全新的时代&#xff0c;为思洣客、合作伙伴和整个经济生态带来了前所未有的机遇和挑战。 SMiC矩阵作为引领数字化经济的新力量&#xff0c;始终致…...

备战蓝桥杯---动态规划的一些思想2

话不多说&#xff0c;直接看题&#xff1a; 1.换根DP&#xff1a; 我们肯定不能对每一个根节点暴力求&#xff0c;我们不妨先求f[1]&#xff0c;我们发现当他的儿子作为根节点时深度和为f[1](n-cnt[i])-cnt[i](cnt[i]表示以i为根的节点数&#xff09;&#xff0c;这样子两遍DFS…...

卫星导航 | 坐标系---地理坐标系与UTM坐标系

卫星导航 | 坐标系---地理坐标系与UTM坐标系 世界坐标系地理坐标系UTM坐标系 全球卫星导航系统(Global Navigation Satelite System,GNSS)&#xff0c;简称卫星导航&#xff0c;是室外机器人定位的一个主要信息来源。 卫星导航能给机器人提供什么信息&#xff1f; 正常工作时&…...

JavaEE之volatile关键字

一.内存可见性问题 什么是内存可见性问题 计算机运行的程序/代码&#xff0c;往往需要访问数据。这些数据往往存在于内存中。 cup使用此变量时&#xff0c;就会把内存中的数据先读出来&#xff0c;加载到cpu寄存器中&#xff0c;再去参与运算。 但是&#xff0c;关键是cpu读…...

代码学习记录10

随想录日记part10 t i m e &#xff1a; time&#xff1a; time&#xff1a; 2024.03.03 主要内容&#xff1a;今天的主要内容是深入了解数据结构中栈和队列&#xff0c;并通过三个 l e e t c o d e leetcode leetcode 题目深化认识。 20. 有效的括号1047. 删除字符串中的所有…...

java——2024-03-03

String类的对象能被修改吗&#xff1f;如果不能需要用什么修改&#xff1f;StringBuilder和StringBuffer的区别&#xff1f;equals和区别谈谈对面向对象的理解重载和重写的区别说一下ArrayList&#xff0c;LinkedList底层实现以及区别什么是哈希冲突&#xff1f;hashMap和conCu…...

Ubuntu安装conda以后,给jupyter安装C++内核

前言 大家都知道&#xff0c;jupyter notebook 可以支持python环境&#xff0c;可以在不断点调试的情况下&#xff0c;打印出当前结果&#xff0c;如果代码错了也不影响前面的内容。于是我就想有没有C环境的&#xff0c;结果还真有。 参考文章&#xff1a; 【分享】Ubuntu安装…...

【谈判】核心思想(抓大放小)

谈判交换&#xff08;抓大放小&#xff09; 一、明确目的 事&#xff1a;must: 非要不可&#xff0c;才会签字 want: 有很好&#xff0c; give: 放掉 三者&#xff0c;会变化 二、明确对象 人&#xff1a;我跟谁谈&#xff1f; 时&#xff1a; 国际形势、国家的政策、他的心…...

洛谷P5908 猫猫和企鹅 做题反思(2024.3.7)

猫猫和企鹅 题目传送门 题目描述 王国里有 n n n 个居住区&#xff0c;它们之间有 n − 1 n-1 n−1 条道路相连&#xff0c;并且保证从每个居住区出发都可以到达任何一个居住区&#xff0c;并且每条道路的长度都为 1 1 1。 除 1 1 1 号居住区外&#xff0c;每个居住区住…...

常见的验证码

一、短信验证码 前端&#xff1a; 用户填写手机号&#xff0c;点击按钮发送请求用户短信得到验证码后&#xff0c;用户填写表单提交 form 表单&#xff0c;进行验证 后台&#xff1a; 随机生成几位验证码并将生成时间、手机号、验证码存储起来&#xff0c;可以存到session、…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中&#xff0c;iftop是网络管理的得力助手&#xff0c;能实时监控网络流量、连接情况等&#xff0c;帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

vscode里如何用git

打开vs终端执行如下&#xff1a; 1 初始化 Git 仓库&#xff08;如果尚未初始化&#xff09; git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

HTML 列表、表格、表单

1 列表标签 作用&#xff1a;布局内容排列整齐的区域 列表分类&#xff1a;无序列表、有序列表、定义列表。 例如&#xff1a; 1.1 无序列表 标签&#xff1a;ul 嵌套 li&#xff0c;ul是无序列表&#xff0c;li是列表条目。 注意事项&#xff1a; ul 标签里面只能包裹 li…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

并发编程 - go版

1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...