代码随想录Day02 数组基础2 leetcode T977有序数组的平方, T209 长度最小的子数组,T59 螺旋矩阵II

news2025/1/12 0:52:46

本文思路和详细解答来源于:

代码随想录

视频讲解见:

双指针法经典题目 | LeetCode:977.有序数组的平方_哔哩哔哩_bilibili

Leetcode T977 有序数组的平方

题目链接:

977. 有序数组的平方 - 力扣(LeetCode)

思路1: 暴力求解

这里先解释一下非递减顺序:

1223445

非递增顺序:

5443221

首先我们可以使用暴力求解,直接创建一个新数组,将原数组的元素平方放入新数组,再将新数组使用快排,就完成了.

时间复杂度:O(nlogn)

class Solution {
public:
    vector<int> sortedSquares(vector<int>& A) {
        for (int i = 0; i < A.size(); i++) {
            A[i] *= A[i];
        }
        sort(A.begin(), A.end()); // 快速排序
        return A;
    }
};

思路2: 双指针写法 

我们发现,平方之后较大的数一定在两边,所以,我们可以创建两个指针,一个指针指向最后一个元素,一个指针指向首元素,两个指针向中间移动,这时候,由于只能先获得较大的数,我们用一个指针指向新创建的数组的最后一个元素,从后向前更新新数组.

class Solution {
    public int[] sortedSquares(int[] nums) {
        int size = nums.length - 1;
        int i,j;
        int k = size;
        int[] result = new int [size + 1];
        for(i = 0,j = size;i<=j;)
        {
            if(nums[i]*nums[i] < nums[j]*nums[j])
            {
                result[k] = nums[j] * nums[j];
                k--;
                j--;
            }
            else
            {
                result[k] = nums[i] * nums[i];
                k--;
                i++;

            }
        }
        return result;


    }
}

这里我们 就用O(n)的时间复杂度解决了问题,仅仅遍历了一次数组,效率还是提升了不少的.

总结:

当出现有序数组的时候,我们可以考虑双指针的解法 

Leetcode T209 长度最小的子数组

题目链接:209. 长度最小的子数组 - 力扣(LeetCode)

 

思路1: 暴力求解(现在跑不过)

这个时候我们很容易想到用两层for循环遍历两次数组,显然代码的时间复杂度是O(n^2),我们只需要给定一个sum记录子区间的总和,subLength记录总区间的长度,两个变量ij记录子序列的起始位置和终止位置,在开始的时候定义一个result作为返回值.

class Solution {
    public int minSubArrayLen(int target, int[] nums) {

        
        int result = Integer.MAX_VALUE;
        int i = 0;//开始位置
        int j = 0;//结束为止
        
        int sum = 0;
        for(i = 0;i<nums.length;i++)
        {
            sum = 0;
            for(j = i;j<nums.length;j++)
            {
                //遍历i到最后
                sum += nums[j];
                if(sum >= target)
                {
                    //取子序列的长度
                    subLength = j-i+1;
                    //找到长度最小的序列
                    result = result < subLength ? result : subLength;
                    break;
                }
            }
        }
        //如果result没变就是没有适合的元素的序列
        return result == Integer.MAX_VALUE? 0: result;
    }
}

总结

算法的总思路是第一次寻找起始位置,第二个for循环是寻找结束位置,从i开始累加,一旦累加的结果大于target就跳出,就说明从此时的i开始寻找到了满足条件的子序列,然后继续遍历以此类推.

思路2:滑动窗口 

总体思想就是不断调整起始位置和终止位置,从而达到我们想要的效果

暴力解法是通过一个for循环是滑动窗口的起始位置,一个for循环是滑动窗口的结束位置,从而达到搜索整个数组的效果.

那么我们这个滑动窗口如何使用一个for循环来解决问题呢?

如果我们使用一个for循环代替起始位置,那难免会又想到暴力解法的思路上去,

所以这个for循环一定代表的是滑动窗口的末尾位置

举例说明:假设target的值是7,我们在 2 3 1 2 4 3这个数组里求最小的子数组

首先我们找到大于等于7的连续子数组 2 3 1 2,   条件:累计和>=7

这个时候我们的窗口就应该缩小了

3 1 2是不满足的,所以我们继续向后找

3 1 2 4满足条件,缩小

1 2 4满足条件,缩小

2 4不满足条件 ,向前走

2 4 3满足条件,缩小

3 4 ,找到答案,返回2

注:图片取自于代码随想录网站,可以在文首点击查看详细解答. 

解答代码: 

class Solution {
    public int minSubArrayLen(int target, int[] nums) {

        //滑动窗口
        int result = Integer.MAX_VALUE;
        int i = 0;//左指针
        int sum = 0;

        for(int j = 0;j<nums.length;j++)
        {
            sum += nums[j];
            while(sum >= target)
            {
                result = Math.min(result,j-i + 1);
                sum -= nums[i++];
            }
        }
        return result == Integer.MAX_VALUE?0:result;
    }
}

注:不一定循环中套用循环就是O(n^2)的时间复杂度,这里是O(n*2)的时间复杂度也就是O(n)的时间复杂度,具体是么时候是O(n*n)什么时候是O(n+n).

这里我们可以看到暴力求解的时候两层都对i操作,也就是元素被操作了n*n次,就是O(n^2)的时间复杂度,这里是 在进窗口操作一次出窗口操作n次,所以是O(n)的时间复杂度.

总结:第一次做滑动窗口的问题,我认为更重要的是掌握这种让窗口动起来的同时不断更新子序列大小和位置的思想.

Leetcode T59 螺旋矩阵II

 提示:1 <= n <= 20

思路: 

题目的关键是保证循环变量中的不变量,我们的目的是用一个二维数组模拟实现这个矩阵,

定义一个起始坐标(start,start),我们定义一个while循环,循环次数是n/2次,那么有同学就会问了,我万一n是奇数怎么办,奇数的话我们的n就可以另外处理,定义一个loop,来控制每次执行完一圈我们向里进一圈.

重点:循环不变量的确定,这里我们一定要搞清楚每一次写入的区间,是左开右闭还是闭区间,这样才能保证代码的书写稳中不乱,这里我们选择的区间的左闭右开区间.

int start = 0;
int count = 1;
int loop = n/2;
int i,j;

解答代码: 

class Solution {
    public int[][] generateMatrix(int n) {
        int[][] arr = new int[n][n];
        //起始地址
        int start = 0;
        //计数器
        int count = 1;
        //用来控制循环
        int loop = 0;
        //用来解决n等于奇数的问题
        int mid = n/2;
        int i,j;
        while(loop++<mid) 
        {
            //顺时针填入填入矩阵元素
            for(j = start;j<n-loop;j++) 
            {
                arr[start][j] = count++;
            }
            for(i = start;i<n-loop;i++)
            {
                arr[i][j] = count++;
            }
            for(;j>=loop;j--)
            {
                arr[i][j] = count++;
            }
            for(;i>=loop;i--)
            {
                arr[i][j] = count++;
            }
            start++;
        }
        if(n%2 == 1)
        {
            arr[mid][mid] = count;
        }
         return arr;

    }
   
}

 总结:

在遇到有序数组时,可以考虑二分法

一定要牢记循环不变量原则,找准循环中的不变量

找一个连续的子数组的总和值,可以想到滑动窗口解决问题

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何满足计算机化系统验证(CSV):制药企业的指南

随着科技的不断发展&#xff0c;制药企业在其日常运营中越来越多地依赖计算机化系统。这些系统涵盖了从研发到生产再到分销的各个领域&#xff0c;它们对于确保药品质量、跟踪生产流程以及维护患者安全至关重要。为了满足监管机构的法规要求&#xff0c;如美国FDA、欧盟Annex 1…

别再费劲配音了!小说推文视频一键生成,并带全自动配音

下面教你轻松一键制作出精彩的小说推文视频。 1. 输入文案生成小说推文视频 小说推文视频可以根据你输入的文案自动生成精美的视频内容&#xff0c;无需手动操作。只需提供文案&#xff0c;小说推文视频就能为你制作出令人惊艳的视频作品。 2. 自动小说推文配音 不用再费心去…

力扣:108. 将有序数组转换为二叉搜索树(Python3)

题目&#xff1a; 给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵 高度平衡 二叉搜索树。 高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。 来源&#xff1a;力扣&#xff08;LeetCode&…

C#的属性讲解

文章目录 属性自动实现属性访问器内写逻辑属性不存储值其他文章 属性 在C#中&#xff0c;属性是一种特殊的成员&#xff0c;用于封装类的字段。它们提供了一种简洁和安全的方式来访问和设置类的状态和行为。 属性由两个访问器组成&#xff1a;get&#xff08;获取器&#xff…

测试工程师需要具备哪些“技能”?

1、良好的沟通 相信大家都在网上看到过各种吐槽程序员不解风情的段子&#xff0c;开怀大笑之余深思&#xff0c;作为一个测试工程师又何尝不是如此&#xff1f;通常沟通技能成为横亘在测试工程师与其他合作部门之间的万丈鸿沟&#xff0c;也成为测试工程师成长的最大瓶颈。下面…

【软件设计师-从小白到大牛】上午题基础篇:第三章 数据库系统

文章目录 前言章节提要一、三级模式两级映射真题链接 二、数据库的设计过程真题链接 三、E-R模型真题链接 四、关系代数SQL基础&#xff08;补充&#xff09; 五、规范化理论1、函数依赖2、价值与用途3、键4、范式5、模式分解 六、并发控制真题链接分布式数据库特点&#xff08…

二值贝叶斯滤波计算4d毫米波聚类目标动静属性

机器人学中有些问题是二值问题&#xff0c;对于这种二值问题的概率评估问题可以用二值贝叶斯滤波器binary Bayes filter来解决的。比如机器人前方有一个门&#xff0c;机器人想判断这个门是开是关。这个二值状态是固定的&#xff0c;并不会随着测量数据变量的改变而改变。就像门…

关于计算机找不到d3dx9_43.dll,无法继续执行代码修复方法

d3dx9_43.dll是一个动态链接库文件&#xff0c;它是DirectX的一个组件&#xff0c;主要用于处理游戏中的图形、声音等多媒体元素。当这个文件丢失时&#xff0c;可能会导致以下问题&#xff1a; 1. 游戏无法正常运行&#xff1a;由于d3dx9_43.dll负责处理游戏中的多媒体元素&a…

Qt地铁智慧换乘系统浅学( 一 )存储站点,线路信息

存储 定义所需要的容器定义最大最小经纬度[统计站点信息 在经纬度网站](https://map.jiqrxx.com/jingweidu/)读取统计的信息存储到容器其他的一些相关函数debug 显示存储的信息更新最小最大经纬度的函数获取两点之间的距离 根据经纬度 定义所需要的容器 extern QMap<QStrin…

寻找单身狗

在一个数组中仅出现一次&#xff0c;其他数均出现两次&#xff0c;这个出现一次的数就被称为“单身狗“。 一.一个单身狗 我们知道异或运算操作符 ^ &#xff0c;它的特点是对应二进制位相同为 0&#xff0c;相异为 1。 由此我们容易知道两个相同的数,进行异或运算得到的结果…

tkinter的Canvas组件,绘画基本知识

一、说明 画布组件是Tkinter画图的最重要组件。画布对象是几何绘制、动画绘制的不二选项&#xff0c;本文专门对画布Canvas进行详细描述&#xff0c;并配以适当代码支持。 二、tkinter的Canvas组件&#xff0c;绘画基本知识 Canvas组件&#xff0c;可以用来绘图&#xff0c;也…

【Java 基础篇】Java反射详解:深入了解Java的镜像世界

Java是一门面向对象的编程语言&#xff0c;其强大之处之一就是能够在运行时检查、获取和操作类、方法、字段等程序元素。这一特性就是通过Java的反射机制实现的。本文将深入介绍Java反射&#xff0c;包括它的基本概念、使用方法、常见应用场景和注意事项。无需担心&#xff0c;…

云计算战略:选择适合你业务的云平台

文章目录 云计算的概述选择云平台的关键因素1. 业务需求2. 预算3. 性能要求4. 数据隐私和合规性 示例&#xff1a;选择适合的云平台业务需求预算性能要求数据隐私和合规性 代码示例&#xff1a;使用云平台服务结论 &#x1f389;欢迎来到云计算技术应用专栏~云计算战略&#xf…

“源启2.0”:从自上而下的解构,到自下而上的重构

从垂直打穿、到应用重构&#xff0c;中电金信赋能行业数字化转型之路既“向下走”、也“向上看”。“向上”先理解和吃透客户的企业战略&#xff0c;进而自上而下地将企业战略拆解为业务架构&#xff0c;“向下”再将业务架构拆解为应用架构和数据架构&#xff0c;并进一步对齐…

JS预解析/编译(变量提升):var(仅声明,无赋值)、function变量 创建作用域

目录 变量提升/预定义 function和var 重名&#xff1a;函数覆盖变量 不执行代码 重复声明&#xff1a;只提升一次 函数形参&#xff1a;变量提升 带 var 和不带 var 全局作用域&#xff1a; window 的属性 私有/函数作用域&#xff1a; 带 var 的是私有变量 IIFE 函…

Linux 终端与进程

有趣的问题 Linux 中的 终端&#xff0c;控制台&#xff0c;TTY&#xff0c;PTY 究竟是什么&#xff1f;它们与进程有什么关系&#xff1f; 历史回顾&#xff1a;控制台 (Console) 控制台是一个直接控制设备的面板 (属于设备的一部分) 计算机设备的控制台&#xff1a;按键 &…

2FSK调制解调VHDL,Quartus

名称&#xff1a;2FSK调制解调VHDL&#xff08;代码在文末付费下载&#xff09; 软件&#xff1a;Quartus 语言&#xff1a;VHDL 要求&#xff1a;使用VHDL实现2FSK的调制和解调&#xff0c;并进行仿真 代码下载&#xff1a;2FSK调制解调VHDL,Quartus_Verilog/VHDL资源下载…

C++ stack queue模拟实现

目录 一.stack 二.queue 三.deque STL中有6大组件&#xff0c;我们前面讲的string/vector/list是容器&#xff0c;还有迭代器&#xff0c;以及算法&#xff08;比如find&#xff0c;swap&#xff0c;reverse&#xff0c;sort&#xff0c;merge函数&#xff09;&#xff0c;仿函…

【Java 基础篇】Java Stream 流详解

Java Stream&#xff08;流&#xff09;是Java 8引入的一个强大的新特性&#xff0c;用于处理集合数据。它提供了一种更简洁、更灵活的方式来操作数据&#xff0c;可以大大提高代码的可读性和可维护性。本文将详细介绍Java Stream流的概念、用法和一些常见操作。 什么是Stream…

bootstrapv4轮播图去除两侧阴影及线框的方法

文章目录 前言一、前提条件&#xff1a;二、bootstrap文档组件展示与实际应用1.官方文档展示如下&#xff1a;没有阴影2.实际应用情况如下&#xff1a; 三、解决方案 前言 这篇文章主要介绍了bootstrapv4轮播图去除两侧阴影及线框的方法,本文通过示例代码给大家介绍的非常详细…