算法归纳【数组篇】

目录

  • 二分查找
    • 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)-1
    low := 0
    for low <= high {
        mid := low + (high-low)/2
        if 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 := 0
    for low < high {
        mid := low + (high-low)/2
        if 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)-1
    for 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-1
	ans := make([]int, n)
	for i <= j {
		lm, rm := nums[i]*nums[i], nums[j]*nums[j]
		if lm > rm {
			ans[k] = lm
			i++
		} else {
			ans[k] = rm
			j--
		}
		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, 0
	sum := nums[0]
	minLen := len(nums) + 1
	for 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-1
    left, right := 0, n-1
    num := 1
    tar := n * n
    matrix := 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] = num
            num++
        }
        top++
        for i := top; i <= bottom; i++ {
            matrix[i][right] = num
            num++
        }
        right--
        for i := right; i >= left; i-- {
            matrix[bottom][i] = num
            num++
        }
        bottom--
        for i := bottom; i >= top; i-- {
            matrix[i][left] = num
            num++
        }
        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-1

	for 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
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深入了解Python的eval函数:基础用法与潜在危险【第118篇—eval函数】

深入了解Python的eval函数&#xff1a;基础用法与潜在危险 在Python中&#xff0c;eval函数是一个强大而灵活的工具&#xff0c;它允许将字符串作为代码来执行。然而&#xff0c;虽然eval在某些情况下非常方便&#xff0c;但它也潜藏着一些潜在的危险&#xff0c;如果不小心使…

php反序列化-字符逃逸看这一篇就够了

反序列化的特性 <?php /* $_SESSION["user"] guest; $_SESSION[function] highlight_file; $_SESSION[img] base64_encode(/d0g3_fllllllag); //d0g3_f1ag.php $serialize_info serialize($_SESSION);echo $serialize_info;*/$str a:3:{s:4:"user&quo…

TikTok播放量低?快来学习提高TikTok账号权重?

许多TikTok账号运营者都会遇到一个难题&#xff0c;那就是视频要么播放量很低&#xff0c;要么0播放&#xff01;不管内容做的多好&#xff0c;最好都是竹篮打水一场空&#xff01;其实你可能忽略了一个问题&#xff0c;那就是账号权重。下面好好跟大家讲讲这个东西&#xff01…

Dynamo小试牛刀(二)——曲线补充

上次写的比较匆忙&#xff0c;只是整理了几个小的例子&#xff0c;并没有过多的说明&#xff0c;这次稍微补充一点&#xff0c;一步步带着你做。 首先需要了解 Math 系列的节点用法&#xff0c;有&#xff1a; Math.sin/cos——正弦 / 余弦 Math.RadiansToDegrees——将弧度转换…

总结Redis的原理

一、为什么要使用Redis 缓解数据库访问压力mysql读请求进行磁盘I/O速度慢&#xff0c;给数据库加Redis缓存&#xff08;参考CPU缓存&#xff09;&#xff0c;将数据缓存在内存中&#xff0c;省略了I/O操作 二、Redis数据管理 2.1 redis数据的删除 定时删除惰性删除内存淘汰…

第四篇【传奇开心果系列】Python的自动化办公库技术点案例示例:深度解读Pandas生物信息学领域应用

传奇开心果博文系列 系列博文目录Python的自动化办公库技术点案例示例系列 博文目录前言一、Pandas生物学数据操作应用介绍二、数据加载与清洗示例代码三、数据分析与统计示例代码四、数据可视化示例代码五、基因组数据分析示例代码六、蛋白质数据分析示例代码七、生物医学图像…

记一次edu证书站的挖洞经历

前言 前几天在网上冲浪的时候无意间看到了一个Edu的站点&#xff0c;是一个很常见的类似MOOC的那种在线学习系统&#xff0c;对外开放&#xff0c;同时有注册和登录功能。对于我这种常年低危的菜鸡来说&#xff0c;这是最愿意看到的&#xff0c;因为一个Web网站有了登录功能&a…

基于Redis自增实现全局ID生成器(详解)

本博客为个人学习笔记&#xff0c;学习网站与详细见&#xff1a;黑马程序员Redis入门到实战 P48 - P49 目录 全局ID生成器介绍 基于Redis自增实现全局ID 实现代码 全局ID生成器介绍 背景介绍 当用户在抢购商品时&#xff0c;就会生成订单并保存到数据库的某一张表中&#…

基于sprinbgoot的火锅店管理系统(程序+数据库+文档)

** &#x1f345;点赞收藏关注 → 私信领取本源代码、数据库&#x1f345; 本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#xff0c;希望你能有所收获&#xff0c;少走一些弯路。&#x1f345;关注我不迷路&#x1f345;** 一、研究背景…

模块自动导入

看的短视频&#xff0c;自己试了下&#xff0c;发现挺好用的&#xff1a;模块自动导入【渡一教育】_哔哩哔哩_bilibili 1. 安装插件 npm i unplugin-auto-import 2. 在vite配置文件&#xff08;vite.config.ts&#xff09;中进行配置&#xff0c; 配置完场后&#xff0c;需要重…

QT和OPENGL安装和集成

1.QT安装 1.1官网下载&#xff1a; 网址&#xff1a;https://download.qt.io/archive/qt/ 1.2 开始安装 点击运行 首先注册sign up 然后Login in 选择安装目录 改为D盘&#xff1a; 选择安装项&#xff1a; 准备安装 开始安装&#xff1a; 安装完成&#xff1a; 1.3测试 …

知行之桥EDI系统数据库进阶功能——动态更新

在知行之桥EDI系统中常用的数据库端口包括&#xff1a;MySQL端口、SQLServer端口以及SQLite端口。本文将为大家介绍数据库端口的进阶功能&#xff0c;通过简单配置实现数据库的动态更新。 实现SQLServer的动态更新 创建一个SQLServer端口&#xff0c;在 设置 选项卡下创建连接…

Python数据分析库之pandera使用详解

概要 在数据科学和数据分析中,数据的质量至关重要。不良的数据质量可能导致不准确的分析和决策。为了确保数据的质量,Python Pandera 库应运而生。本文将深入介绍 Python Pandera,这是一个用于数据验证和清洗的库,并提供丰富的示例代码,帮助大家充分利用它来提高数据质量…

北斗卫星引领智能油气管线革新

北斗卫星引领智能油气管线革新 现代化的油气管线系统已成为国家经济发展的重要基础设施&#xff0c;而北斗卫星则为这些管线注入了新的活力。北斗卫星作为中国自主研发的卫星导航定位系统&#xff0c;其准确度和稳定性在全球范围内享有盛誉。在智能化时代的背景下&#xff0c;…

B 站画质补完计划:视频超分让像素细腻生动

目前, 超分算法已成功投入线上点播业务,并已支持了大量视频的高分辨率视频流生产。未来,我们将持续在覆盖范围、主观效果和部署灵活度等方面进行算法的迭代更新,以在直播、点播、应用端等多个场景为视频画质提供更大的增益。 1 前言 为了给用户提供更清晰的画质体验,B站自…

Tablesgenerator 使用

1.在线工具网站 Create LaTeX tables online – TablesGenerator.com 2.按住 shift 选择边框 3.选择标题和双栏布局 4.保存和加载表格 5.默认风格与三线表 Default table style使用 \hline 而 Booktabs 使用 \toprule、\midrule和\bottomrule。 \toprule、\midrule和 \botto…

echarts x轴名称过长tip显示全称

xAxis的axisLabel的内容如下&#xff1a; axisLabel: { rotate: -45, color: document.body.className.indexOf(custom-f4c46d) > -1 ? #fff : #343434, // 显示省略号操作&#xff08;第一步&#xff09; formatter: function (value) { var val if (value.length >…

【网络层】IP多播技术的相关基本概念(湖科大慕课自学笔记)

IP多播 1&#xff1a;IP多播技术的相关基本概念 我们简单举例&#xff0c;如下图所示&#xff1a; 一共有60个主机要接受来自视频服务器的同一个节目&#xff0c;如果采用单播方式&#xff0c;则视频服务器要发送60份&#xff0c;这些视频节目通过路由器的转发&#xff0c;最…

windows10下powershell中如何在后台执行python程序

背景 在windows10本地执行时间较长的程序时&#xff0c;很容易忘记&#xff0c;随手关掉编译器&#xff0c;程序就此中断&#xff0c;造成精神伤害。 功能介绍 如果不管不挂起&#xff0c;不管日志重定向&#xff0c;我要运行的python脚本的命令很简单 python CUTE_pipelin…

在人工智能领域,如何平衡技术进步和人类安全?

人工智能&#xff08;AI&#xff09;技术的迅速发展为人类社会带来了许多潜在益处&#xff0c;但同时也引发了一系列安全和伦理挑战。在这个领域&#xff0c;如何平衡技术进步与人类安全成为了至关重要的议题。本文将探讨在人工智能领域中平衡技术进步与人类安全的方法&#xf…