算法打卡|Day2 数组part02
Day2 数组part02
今日任务:977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II
Problem: 977. 有序数组的平方
思路
首先分析这道题,它是一道有序数组平方后排序的题目。观察平方后数组的特性我们发现,平方后最大的数永远是在数组的前后两端。例如【-1,-2,-3,0,1,2】,平方后去掉符号所以最大的数总是在两侧。
所以本题考虑运用前后双指针算法,一前一后两个指针,比较谁的值大就更新到新的数组中去,直到它们相遇(本题要求新数组从小到大,所以我们从后往前放大数)。
解题方法
双指针算法
复杂度
- 时间复杂度:
$O(n)$
(补充:快排的时间复杂度:for循环:O(n) ️ 快排:O(nlogn))
Code
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int k = nums.size() - 1;
vector<int> newnums(nums.size(),0);//记住这种初始化操作,可以设置vector长度
for(int j = nums.size()-1, i = 0; i<=j;){
if(nums[i]*nums[i] < nums[j]*nums[j]){
newnums[k] = nums[j]*nums[j];
k--;
j--;
} else{
newnums[k] = nums[i]*nums[i];
k--;
i++;
}
}
return newnums;
}
};
Problem: 209. 长度最小的子数组
思路
1.前缀和+二分思路:观察到是求连续子数组的和的问题,我们可以用前缀和。首先我们对整个数组求前缀和数组,然后依次对前缀和数组每一项的值加上目标值去二分搜索不超过这个和的最小值那一项,这样得到的项便对应了连续子数组和的最后一项,我们用这一项减去遍历到的起始坐标,就得到了长度。然后依次遍历,依次比较最小长度即可。
2.双指针思路:其实写滑动窗口不需要背步骤,只需要写的时候问自己四个问题,而这四个问题也正是滑动窗口真正核心的部分。解决了这四个问题,代码也写出来了。
1.增大窗口时,要更新窗口内的什么数据?
要计算窗口内数字的和。
2.什么时候窗口要缩小(shrink)?
当窗口内的和大于等于目标长度时缩小。
3.窗口缩小时,更新窗口内的什么数据?
更新窗口长度,并与之前更新的长度比较得出最小长度。另外由于缩小窗口,在缩小窗口之前要先减去当前left指针所在的数值。
4.什么时候更新结果?
在循环缩小窗口的适合更新最小长度。
链接:https://zhuanlan.zhihu.com/p/142048740
解题方法
双指针算法|前缀和+二分
复杂度
- 时间复杂度:
滑动窗口:$O(n)$
滑动窗口算法的时间复杂度通常是O(n) 的,其中 n 表示字符串或数组的长度。这是因为滑动窗口算法只需要对每个元素至多遍历一遍,同时也只需要在窗口的左右边界上移动,因此总的操作次数不会超过 2n 次。
前缀和+二分:$O(n+lgn)$
- 空间复杂度:
$O(1)$
Code1:双指针
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int n = nums.size();
int l=0,r=0;
int minSubArrayLen = INT_MAX;
int sum=0;
while(r<n){
sum += nums[r];
while(sum>=target){
int len = r-l+1;
minSubArrayLen = min(minSubArrayLen,len);
sum-=nums[l];
l++;
}
r++;
}
return (minSubArrayLen == INT_MAX)?0:minSubArrayLen;
}
};
Code2:前缀和+二分
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int n = nums.size();
vector<int> preSum(n + 1, 0);
for(int i = 1; i <= n; i++) preSum[i] = preSum[i - 1] + nums[i - 1];
int minSubArrayLen = INT_MAX;
//每一项遍历搜索
for(int i = 0; i< n; i++){
int tar =target+preSum[i];
int l = i-1;//区间范围搜索
int r = n+1;//区间范围搜索
while(l+1 != r){
int mid =(l+r)/2;
if(preSum[mid] < tar){
l = mid;
}
else r = mid;
}
//输出答案时候注意过滤特殊情况
if(l!=i-1 && r!=n+1 ) minSubArrayLen = min(minSubArrayLen, r - i);
}
return minSubArrayLen == INT_MAX ? 0 : minSubArrayLen;
}
};
Problem: 59. 螺旋矩阵 II
思路
蛇形矩阵问题,我们可以用偏移量控制蛇的姿态,撞墙(越界)或重复走路代表着换方向。另外要注意边界条件,我们判断的是如果沿着当前方向走,下一步走出去了才换方向。
解题方法
利用 int dx[4] = {0, 1, 0, -1}和int dy[4] = {1, 0, -1, 0}去模拟四个方向的偏移量。
复杂度
- 时间复杂度:
$O(n^2)$,取决于这个数组的大小
- 空间复杂度:
$O(1)$
Code
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> nums(n, vector<int>(n, 0));
int x = 0, y = 0;
//竖着看这是在模拟每个偏移量,分别是向上,向右,向下,向左
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
//这是在记录方向,0。1。2。3代表取数组不同的方向
int d = 0;
for (int i = 1; i <= n * n; i++) {
nums[x][y] = i;
//这几步骤可以合并在一起,定义两个新的变量的目的是判断按着原来的方向继续走是否会撞墙或走了重复的路。
int new_x = x + dx[d];
int new_y = y + dy[d];
if (new_x < 0 || new_x >= n || new_y < 0 || new_y >= n || nums[new_x][new_y] != 0) {
d = (d + 1) % 4;//取模运算是一个周期函数,要记住,换方向就用取模运算,模几代表在几个数之间循环。
}
x = x + dx[d];
y = y + dy[d];
}
return nums;
}
};
算法打卡|Day2 数组part02的更多相关文章
- LeetCode初级算法的Python实现--数组
LeetCode初级算法的Python实现--数组 # -*- coding: utf-8 -*- """ @Created on 2018/6/3 17:06 @aut ...
- 算法与数据结构基础 - 数组(Array)
数组基础 数组是最基础的数据结构,特点是O(1)时间读取任意下标元素,经常应用于排序(Sort).双指针(Two Pointers).二分查找(Binary Search).动态规划(DP)等算法.顺 ...
- 前端与算法 leetcode 189. 旋转数组
目录 # 前端与算法 leetcode 189. 旋转数组 题目描述 概要 提示 解析 算法 # 前端与算法 leetcode 189. 旋转数组 题目描述 189. 旋转数组 概要 把他当做一到简单 ...
- 坐标轴刻度取值算法-基于魔数数组-源于echarts的y轴刻度计算需求
本文链接:https://blog.csdn.net/qq_26909801/article/details/96966372数值型坐标轴刻度计算算法前言算法描述上代码代码运行效果结语前言因实习的公司 ...
- KMP 算法中的 next 数组
KMP 算法中对 next 数组的理解 next 数组的意义 此处 next[j] = k:则有 k 前面的浅蓝色区域和 j 前面的浅蓝色区域相同: next[j] 表示当位置 j 的字符串与主串不匹 ...
- c语言经典算法——查找一个整数数组中第二大数
题目: 实现一个函数,查找一个整数数组中第二大数. 算法思想: 设置两个变量max1和max2,用来保存最大数和第二大数,然后将数组剩余的数依次与这两个数比较,如果这个数a比max1大,则先将max1 ...
- 字符串模式匹配之KMP算法图解与 next 数组原理和实现方案
之前说到,朴素的匹配,每趟比较,都要回溯主串的指针,费事.则 KMP 就是对朴素匹配的一种改进.正好复习一下. KMP 算法其改进思想在于: 每当一趟匹配过程中出现字符比较不相等时,不需要回溯主串的 ...
- KMP算法 --- 深入理解next数组
在KMP算法中有个数组,叫做前缀数组,也有的叫next数组. 每一个子串有一个固定的next数组,它记录着字符串匹配过程中失配情况下可以向前多跳几个字符. 当然它描述的也是子串的对称程度,程度越高,值 ...
- 窥探算法之美妙——寻找数组中最小的K个数&python中巧用最大堆
原文发表在我的博客主页,转载请注明出处 前言 不论是小算法或者大系统,堆一直是某种场景下程序员比较亲睐的数据结构,而在python中,由于数据结构的极其灵活性,list,tuple, dict在很多情 ...
- 翻阅《数据结构与算法javascript描述》--数组篇
导读: 这篇文章比较长,介绍了数组常见的操作方法以及一些注意事项,最后还有几道经典的练习题(面试题). 数组的定义: JavaScript 中的数组是一种特殊的对象,用来表示偏移量的索引是该对象的属性 ...
随机推荐
- AI 协助办公 |记一次用 GPT-4 写一个消息同步 App
GPT-4 最近风头正劲,作为 NebulaGraph 的研发人员的我自然是跟进新技术步伐.恰好,现在有一个将 Slack channel 消息同步到其他 IM 的需求,看看 GPT-4 能不能帮我完 ...
- STL-stack(ACM)
1.没有.clear()操作,需要手动pop() 重构函数(默认) stack<int> a; 基础操作 a.push() // 入栈 a.pop() // 弹出栈顶元素 a.empty( ...
- RedHat7.4配置yum源(原创!详细易懂)
redhat7 .4配置centOS yum源(自带yum文件) 1.定位到yum的配置文件 root@192.168.6.129:/etc# cd yum.repos.d 2.检查yum是否安装,以 ...
- Docker和Kubernetes与容器自动化扩展:最佳实践
目录 1. 引言 2. 技术原理及概念 2.1 基本概念解释 2.2 技术原理介绍 2.3 相关技术比较 3. 实现步骤与流程 3.1 准备工作:环境配置与依赖安装 3.2 核心模块实现 3.3 集成 ...
- 深入Python网络编程:从基础到实践
Python,作为一种被广泛使用的高级编程语言,拥有许多优势,其中之一就是它的网络编程能力.Python的强大网络库如socket, requests, urllib, asyncio,等等,让它在网 ...
- 根据模板动态生成word(二)使用poi生成word
@ 目录 一.准备模板 1.创建模板文件 二.代码实践 1.引入依赖 2.自定义XWPFDocument 2.公用的方法和变量 3.工具类引用的包名 4.段落文本替换 5.图片替换 6.表格替换 7. ...
- [NOIP2011 提高组] 聪明的质监员【题解】
题目 小 T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有 \(n\) 个矿石,从 \(1\) 到 \(n\) 逐一编号,每个矿石都有自己的重量 \(w_i\) 以及价值 \(v_i\) ...
- Mybatis(Map)
Map 假设,我们的实体类,或者数据库中的表,字段或参数过多,我们应当考虑使用map 创建接口 //万能的mapper,我们不需要知道数据库里面有什么,是一个键值对的表现 //我们只需查询对应的字段 ...
- LeetCode 周赛上分之旅 #35 两题坐牢,菜鸡现出原形
️ 本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 和 [BaguTree Pro] 知识星球提问. 学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思 ...
- 快速切换 nodejs 的版本
最近在开发一个常驻进程.定时任务统一调度系统,以应对开发在进程管理方面遇到的各种复杂问题. 组里开发项目,一般来说是一个人承包整个项目,包括调度器设计,还有后台系统.我还有一部分工作,是队列相关的信息 ...