算法打卡day2|数组篇|Leetcode 977.有序数组的平方、 209.长度最小的子数组、59.螺旋矩阵II

本文主要是介绍算法打卡day2|数组篇|Leetcode 977.有序数组的平方、 209.长度最小的子数组、59.螺旋矩阵II,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 算法题

Leetcode 977.有序数组的平方 

题目链接:  977.有序数组的平方

大佬视频讲解:977.有序数组的平方

个人思路

第一时间就只想到暴力解法,双重循环一个循环比较一个循环赋值;但这样可能会超时,所以还能用双指针,因为这个数组是递增数组,也就是说平方后最大的值只能在两边,那么前后各一个指针,比较其值,再根据大小放进新的数组中就能解决,这也是空间换时间的方法;

解法
暴力解法

循环赋值然后排序;

class Solution {public int[] sortedSquares(int[] nums) {for(int i=0;i<nums.length;i++){//暴力循环求值nums[i]*=nums[i];}Arrays.sort(nums);//排序return nums;}
}

时间复杂度:O(nlog n);(一个for循环为n,再加上排序的nlogn,和为n+nlogn ,取最大的时间复杂度即为nlogn)

空间复杂度:O(1);(没有使用多余空间)

双指针

left指向起始位置,right指向终止位置。定义一个新数组newNums,和A数组一样的大小,根据平方的大小来从数组newNums后往前赋值。

class Solution {public int[] sortedSquares(int[] nums) {int len=nums.length;//数组的长度int left=0; int right=len-1;//双指针int[] newNums=new int[len];//新数组int index=len-1;//新数组赋值的指针while(left<=right){if (nums[left] * nums[left] > nums[right] * nums[right]) {newNums[index]=nums[left]*nums[left];//新数组赋值index--;//新数组指针往前移++left;//起始指针往前移}else{newNums[index]=nums[right]*nums[right];//新数组赋值index--;--right;//结尾指针往后移}}return newNums;}
}

时间复杂度:O(n);(最糟糕的可能就是把数组全遍历一遍,因此为On)

空间复杂度:O(n);(使用多一个数组存值)

Leetcode 209.长度最小的子数组

题目链接:209.长度最小的子数组

大佬视频讲解:209.长度最小的子数组视频讲解

个人思路

一开始又想到暴力解法,但这样明显会超时;然后...就没思路了。(之前刷过好几次滑动窗口还是想不起来,菜得多练呀/无奈)

解法
滑动窗口

滑动窗口就是不断的调节子序列的起始位置和终止位置

其中主要确定如下三点:

  1. 窗口的定义;窗口就是 满足其和 ≥ target  的长度最小的 连续 子数组。
  2. 窗口的起始位置如何移动:如果当前窗口的值大于target 了,窗口就要向前移动了(也就是该缩小了)。
  3. 窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。

如果还是比较抽象建议看看视频209.长度最小的子数组视频讲解

class Solution {public int minSubArrayLen(int target, int[] nums) {//暴力解法,从头开始遍历,计算达到目标值的张最小连续数组即可;这样会超时int start=0;//滑动窗口的起始位置int sum=0;//滑动窗口的和int answer=Integer.MAX_VALUE;//结果数组长度for(int end=0;end<nums.length;end++){//滑动窗口的结束位置sum+=nums[end];while(sum>=target){answer=Math.min(answer,end-start+1);//用当前滑动窗口的长度与之前长度对比sum-=nums[start++];//不断变更start(子序列的起始位置)}}return answer==Integer.MAX_VALUE ? 0:answer;// 如果说明没有符合条件的子序列,即answer没有被赋值的话,就返回0,}
}

时间复杂度:O(n);(一个 for循环加上一个while没有嵌套,所以是n+n,2n)

空间复杂度:O(1);(没有使用多余空间)

Leetcode  59.螺旋矩阵II

题目链接:59.螺旋矩阵II

大佬视频讲解:59.螺旋矩阵II视频讲解

个人思路

这道题之前做过,没怎么搞懂,只记得是找规律,那先画图看看;画一个n为4和5的数组,螺旋循环后发现规律如下:有四个方向赋值;这四个方向的赋值数量刚刚开始都是n-1;如果n为奇数,则会剩下中间的值没有赋值;循环次数正好是n/2;根据这些规律怎么写代码也是个难题,还得多练

解法
找规律

顺时针画矩阵的过程:

  1. 上行;从左到右填充数据
  2. 右列;从上到下填充数据
  3. 下行;从右到左填充数据
  4. 左列:从下到上填充数据

由外向内一圈一圈这么画下去。可以发现这里的边界条件非常多,在一个循环中,如此多的边界条件,得按照固定规则来遍历,每画一条边都要坚持一致的左闭右开,或者左开右闭的原则,这样这一圈才能按照统一的规则画下来。

下面的是按照左闭右开规则

class Solution {public int[][] generateMatrix(int n) {int loop = 0;  // 控制循环次数int start = 0;  // 每次循环的开始点(start, start)int count = 1;  // 定义填充数字int[][] res = new int[n][n];//结果数组int i, j;while (loop++ < n / 2) { // 先判断边界后,再自增1,以此循环(n-loop)for (j = start; j < n - loop; j++) {// 上侧从左到右填充数据res[start][j] = count++;}for (i = start; i < n - loop; i++) {// 右侧从上到下填充数据res[i][j] = count++;}for (; j >= loop; j--) {// 下侧从右到左填充数据res[i][j] = count++;}for (; i >= loop; i--) {// 左侧从下到上填充数据res[i][j] = count++;}start++;}if (n % 2 == 1) {//判断n为奇数还是偶数,若为奇数,循环填充后还剩一个中间数没填;res[start][start] = count;}return res;}
}

时间复杂度:O(n^2);(模拟遍历二维矩阵的时间)

空间复杂度:O(1);(没有使用多余空间)

以上是个人的思考反思与总结,若只想根据系列题刷,参考卡哥的网址代码随想录算法官网

这篇关于算法打卡day2|数组篇|Leetcode 977.有序数组的平方、 209.长度最小的子数组、59.螺旋矩阵II的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/749872

相关文章

C++初始化数组的几种常见方法(简单易懂)

《C++初始化数组的几种常见方法(简单易懂)》本文介绍了C++中数组的初始化方法,包括一维数组和二维数组的初始化,以及用new动态初始化数组,在C++11及以上版本中,还提供了使用std::array... 目录1、初始化一维数组1.1、使用列表初始化(推荐方式)1.2、初始化部分列表1.3、使用std::

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu

Python中的随机森林算法与实战

《Python中的随机森林算法与实战》本文详细介绍了随机森林算法,包括其原理、实现步骤、分类和回归案例,并讨论了其优点和缺点,通过面向对象编程实现了一个简单的随机森林模型,并应用于鸢尾花分类和波士顿房... 目录1、随机森林算法概述2、随机森林的原理3、实现步骤4、分类案例:使用随机森林预测鸢尾花品种4.1

JAVA中整型数组、字符串数组、整型数和字符串 的创建与转换的方法

《JAVA中整型数组、字符串数组、整型数和字符串的创建与转换的方法》本文介绍了Java中字符串、字符数组和整型数组的创建方法,以及它们之间的转换方法,还详细讲解了字符串中的一些常用方法,如index... 目录一、字符串、字符数组和整型数组的创建1、字符串的创建方法1.1 通过引用字符数组来创建字符串1.2

基于Redis有序集合实现滑动窗口限流的步骤

《基于Redis有序集合实现滑动窗口限流的步骤》滑动窗口算法是一种基于时间窗口的限流算法,通过动态地滑动窗口,可以动态调整限流的速率,Redis有序集合可以用来实现滑动窗口限流,本文介绍基于Redis... 滑动窗口算法是一种基于时间窗口的限流算法,它将时间划分为若干个固定大小的窗口,每个窗口内记录了该时间

vue如何监听对象或者数组某个属性的变化详解

《vue如何监听对象或者数组某个属性的变化详解》这篇文章主要给大家介绍了关于vue如何监听对象或者数组某个属性的变化,在Vue.js中可以通过watch监听属性变化并动态修改其他属性的值,watch通... 目录前言用watch监听深度监听使用计算属性watch和计算属性的区别在vue 3中使用watchE

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第