【代码随想录笔记】数组

news2024/12/24 8:25:11

目录

1、二分查找

2、移除元素

3、有序数组的平方

4、螺旋矩阵II


1、二分查找

对于二分搜索法,有两个边界问题是容易把握不准的

1. 是left < right还是left <= right

2. 当nums[middle] > target时,需要更新右边界,那是right = middle,还是right = middle - 1

对于这两个问题,其实是需要根据二分法维护的区间来判断的,二分法维护的区间主要有两种,左闭右闭和左闭右开

首先,我们来看第一个问题,在讨论left和right之间是否能有等号时,实际上就是看等号成立时,对于这个区间是否有意义,当维护的区间是左闭右闭,此时是有意义的,相当于这个区间只有一个值,当维护的区间是左闭右开,此时是没有意义的,因为此时区间里面一个值都没有。并且,对于左闭右闭的区间,如果不加上等号,还会少判断一个值。所以,对于左闭右闭区间是left <= right,对于左闭右开区间是left < right

然后,我们来看第二个问题。当nums[middle] > target时,需要更新右边界,对于左闭右闭区间,因为nums[middle]这个值已经明确是大于target了,所以不需要再放在区间里面取判断,所以是right = middle - 1,对于左闭右开区间,则是right = middle。左边都是闭的,所以更新左边界时都是left = middle + 1

并且还要注意,初始化right时,对于左闭右闭区间,right = num.size() - 1,对于左闭右开区间,right = nums.size()

控制左闭右闭区间和左闭右开区间也称为控制循环不变量

左闭右闭的代码:

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0,right = nums.size() - 1;
        while(left <= right)
        {
            int middle = (left + right) / 2;
            if(nums[middle] == target) return middle;
            else if(nums[middle] < target) left = middle + 1;
            else right = middle - 1;
        }
        return -1;
    }
};

左闭右开的代码:

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0,right = nums.size();
        while(left < right)
        {
            int middle = (left + right) / 2;
            if(nums[middle] == target) return middle;
            else if(nums[middle] < target) left = middle + 1;
            else right = middle;
        }
        return -1;
    }
};

2、移除元素

这道题很容易就想到使用vector的erase接口来完成即可,但是一般直接使用库函数就可以解决的题目,出题者往往不是想让你用库函数,而是为了让你模拟实现库函数。vector的erase接口就是当遍历到的值是需要删除的元素时,后面全部的元素都往前挪动一位,覆盖掉需要删除的值

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int n = nums.size();
        for(int i = 0;i<n;i++)
        {
            if(nums[i] == val)
            {
                for(int j = i;j < n - 1;j++) nums[j] = nums[j + 1];
                n--;
                i--;
            }
        }
        return n;
    }
};

但是,这种方法的时间复杂度是O(N^2),这个时候我们可以使用双指针算法,来将时间复杂度降到O(N)

定义一个快指针和一个慢指针,当快指针从前向后遍历数组,当快指针指向的值不是val时,就将快指针指向的值赋值给慢指针指向的值,然后两指针都向后走,当快指针指向的值等于val时,就只让快指针向后走

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int n = nums.size(),left = 0,right = 0;
        while(right < n)
        {
            if(nums[right] != val) nums[left++] = nums[right++];
            else right++;
        }
        return left;
    }
};

3、有序数组的平方

这道题很容易就能想到暴力解法,就是先将数组中的每个数都平方了,然后再用sort对其进行排序,这样的时间复杂度是O(N*logN)

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        int n = nums.size();
        for(int i = 0;i<n;i++) nums[i] = nums[i] * nums[i];
        sort(nums.begin(),nums.end());
        return nums;
    }
};

我们会发现,将数组中的每个数都平方之后,这个数组最大的数都是在数组的两边,所以我们可以利用这个性质,使用双指针算法将时间复杂度降到O(N)

额外创建一个数组,让两指针,一个从头开始,一个从尾开始,选择两指针指向的值中大的哪一个,将其放到额外创建的数组的后面

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        int n = nums.size();
        for(int i = 0;i<n;i++) nums[i] *= nums[i];
        vector<int> v(n);
        int left = 0,right = n - 1,k = n - 1;
        while(left <= right)
        {
            if(nums[left] <= nums[right]) v[k--] = nums[right--];
            else v[k--] = nums[left++];
        }
        return v;
    }
};

注意,while循环的条件一定要是left <= right,有等号,否则可能会导致漏掉一个数据

4、螺旋矩阵II

首先,要做这道题就需要先定义好循环不变量,也就是每次在操作一行或者一列时,是左闭右开,或者是怎么样的,这样才能够保证在循环中不会出现泰复杂的边界问题。在这里,我们采用左闭右开的方式来解决问题。

while循环一次就是处理1圈,所以一个n行n列的数组,我们需要处理loop = n / 2圈,当n是偶数时,刚刚和,当n是奇数时,会剩下一个位置没有处理,最后再赋值即可

1圈当中我们会分成4个部分来处理,分别对应两行两列,并且对于每一行,都是左开右闭的,即每一行或每一列的最后一个位置是不在这一行或这一列处理的,留给下一次处理

会定义一个startx和starty来定义每一圈的起始位置,同时也是结束位置,最先开始都是0,一圈完成之后就都变成1,依次类推

还要定义一个offest来控制每一行或每一列的结束位置

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> vv(n, vector<int>(n, 0));
        int loop = n / 2; // 判断需要几圈
        int startx = 0,starty = 0; // 每一圈的起始位置
        int offest = 1; // 控制结束位置
        int count = 1; // 放入数组的数字
        int i,j;
        while(loop--)
        {
            for(j = startx;j < n - offest;j++)
            {
                vv[startx][j] = count++;
            }
            for(i = starty;i < n - offest;i++)
            {
                vv[i][j] = count++;
            }
            for(;j > starty;j--)
            {
                vv[i][j] = count++;
            }
            for(;i > startx;i--)
            {
                vv[i][j] = count++;
            }
            startx++;
            starty++;
            offest++;
        }
        if(n % 2 == 1) vv[n/2][n/2] = count;
        return vv;
    }
};

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

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

相关文章

【深度学习入门篇 ⑥】PyTorch搭建卷积神经网络

【&#x1f34a;易编橙&#xff1a;一个帮助编程小伙伴少走弯路的终身成长社群&#x1f34a;】 大家好&#xff0c;我是小森( &#xfe61;ˆoˆ&#xfe61; ) &#xff01; 易编橙终身成长社群创始团队嘉宾&#xff0c;橙似锦计划领衔成员、阿里云专家博主、腾讯云内容共创官…

‍我想我大抵是疯了,我喜欢上了写单元测试

前言 大家好我是聪。相信有不少的小伙伴喜欢写代码&#xff0c;但是对于单元测试这些反而觉得多此一举&#xff0c;想着我都在接口文档测过了&#xff01;还要写什么单元测试&#xff01;写不了一点&#xff01;&#xff01; 由于本人也是一个小小程序猿&#x1f649;&#xf…

Unity | Shader基础知识(第十八集:Stencil应用-透视立方盒子)

目录 一、前言 二、场景布置 三、 shader部分 1.图片的部分 2.图片部分纯净代码 3.遮罩部分复习 4.深度写入 ZWrite 5.颜色遮罩ColorMask 6.遮罩纯净代码 四、场景中shader使用 五、作者的碎碎念 一、前言 因为这个内容稍微有点多&#xff0c;我尽力讲清楚了&#x…

VAE论文阅读

在网上看到的VAE解释&#xff0c;发现有两种版本&#xff1a; 按照原来论文中的公式纯数学推导&#xff0c;一般都是了解生成问题的人写的&#xff0c;对小白很不友好。按照实操版本的&#xff0c;非常简单易懂&#xff0c;比如苏神的。但是却忽略了论文中的公式推导&#xff…

jquery中pdf在页面的显示和导出

jquery中pdf在页面的显示和导出 01 显示pdf01 .pdf结尾在线接口显示到页面 &#xff08;pdf.js库怎么安装及使用&#xff09;&#xff1a;只显示一页02 如何用PDF.JS显示整个PDF (而不仅仅是一页)&#xff1f;03 jQuery实现在线预览PDF文件(通过a标签链接跳转)&#xff1a; 02 …

【网络安全】PostMessage:分析JS实现XSS

未经许可&#xff0c;不得转载。 文章目录 前言示例正文 前言 PostMessage是一个用于在网页间安全地发送消息的浏览器 API。它允许不同的窗口&#xff08;例如&#xff0c;来自同一域名下的不同页面或者不同域名下的跨域页面&#xff09;进行通信&#xff0c;而无需通过服务器…

【STM32 HAL库】全双工DMA双buffer的I2S使用

1、配置I2S 我们的有效数据是32位的&#xff0c;使用飞利浦格式。 2、配置DMA **这里需要注意&#xff1a;**i2s的DR寄存器是16位的&#xff0c;如果需要发送32位的数据&#xff0c;是需要写两次DR寄存器的&#xff0c;所以DMA的外设数据宽度设置16位&#xff0c;而不是32位。…

ArrayLis练习

代码呈现 import java.util.ArrayList;public class ArrayListTest {public static void main(String[] args) {//创建集合ArrayList<String> list new ArrayList();//添加元素list.add("A");list.add("B");list.add("C");list.add(&quo…

222.买卖股票的最佳时机(力扣)

代码解决 class Solution { public:int maxProfit(vector<int>& prices) {// 初始化最小买入价为第一个价格int min1 prices[0];// 初始化最大利润为0int max1 0;// 从第二天开始遍历价格数组for (int i 1; i < prices.size(); i) {// 计算当前价卖出的利润&a…

C++:智能指针shared_ptr、unique_ptr、weak_ptr的概念、用法即它们之间的关系

智能指针 (1)概述 A.Why&#xff08;C为什么引入智能指针&#xff09; C引入智能指针的根本原因就是解决手动管理动态内存所带来的问题&#xff0c;手动管理动态内存常见的问题如下&#xff1a;内存泄漏、悬挂指针、释放操作未定义等 内存泄漏问题&#xff1a; 当程序用光了它…

React的usestate设置了值后马上打印获取不到最新值

我们在使用usestate有时候设置了值后&#xff0c;我们想要更新一些值&#xff0c;这时候&#xff0c;我们要想要马上获取这个值去做一些处理&#xff0c;发现获取不到&#xff0c;这是为什么呢&#xff1f; 效果如下&#xff1a; 1、原因如下 在React中,当你使用useState钩子…

线程安全(七)ReentrantLock 简介、Condition 条件变量、锁的工作原理、synchronized 与 Lock 的区别

目录 一、ReentrantLock 简介1.1 Reentrant 的特性:1.2 基本语法1.3 ReentrantLock 的主要方法:1.4 lock()、tryLock()、lockInterruptibly() 的区别:二、Condition 条件变量2.1 什么是 Condition 条件变量?2.2 Condition 的核心方法:2.3 Condition 使用示例1:等待与唤醒…

PJA1介导的焦亡抑制是鼻咽癌产生耐药性的驱动因素

引用信息 文 章&#xff1a;PJA1-mediated suppression of pyroptosis as a driver of docetaxel resistance in nasopharyngeal carcinoma. 期 刊&#xff1a;Nature Communications&#xff08;影响因子&#xff1a;14.7&#xff09; 发表时间&#xff1a;2024年6月2…

LLaMA-Factory

文章目录 一、关于 LLaMA-Factory项目特色性能指标 二、如何使用1、安装 LLaMA Factory2、数据准备3、快速开始4、LLaMA Board 可视化微调5、构建 DockerCUDA 用户&#xff1a;昇腾 NPU 用户&#xff1a;不使用 Docker Compose 构建CUDA 用户&#xff1a;昇腾 NPU 用户&#xf…

变阻器与电位器有什么区别?

变阻器和电位器都是可以改变电阻值的电子元件&#xff0c;它们在电路中的作用和调节方式有一定的相似性&#xff0c;但它们之间还是存在一些区别的。 1. 结构上的区别&#xff1a;变阻器主要由固定电阻体和可动滑片组成&#xff0c;通过滑动滑片来改变电阻体的电阻值。而电位器…

数据库(创建数据库和表)

目录 一&#xff1a;创建数据库 二&#xff1a;创建表 2.1&#xff1a;创建employees表 2.2&#xff1a;创建orders表 2.3&#xff1a;创建invoices表 一&#xff1a;创建数据库 mysql> create database mydb6_product; Query OK, 1 row affected (0.01 sec) mysql&g…

linux centos limits.conf 修改错误,无法登陆问题修复 centos7.9

一、问题描述 由于修改/etc/security/limits.conf这个文件中的值不当&#xff0c;重启后会导致其账户无法远程登录&#xff0c;本机登录。 如改成这样《错误示范》&#xff1a; 会出现&#xff1a; 二、解决 现在知道是由于修改limits.conf文件不当造成的&#xff0c;那么就…

智慧农业新纪元:解锁新质生产力,加速产业数字化转型

粮食安全乃国家之根本&#xff0c;“浙江作为农业强省、粮食生产重要省份&#xff0c;在维护国家粮食安全大局中肩负着重大使命。浙江粮食产业经济年总产值已突破4800亿元&#xff0c;稳居全国前列&#xff0c;然而&#xff0c;同样面临着规模大而不强、质量效益有待提升、数字…

JVM高频面试点

文章目录 JVM内存模型程序计数器Java虚拟机栈本地方法栈Java堆方法区运行时常量池 Java对象对象的创建如何为对象分配内存 对象的内存布局对象头实例数据对齐填充 对象的访问定位 垃圾收集器找到垃圾引用计数法可达性分析&#xff08;根搜索法&#xff09; 引用概念的扩充回收方…

字符数组的魅力:C语言字符数组与字符串编程实践

1.概念 字符数组&#xff0c;数组元素是char(字符型)的数组&#xff0c;它可以是一维数组&#xff0c;也可以是二维数组。 2.定义的时候赋值 char ch1[]{c,h,i,n,a}; char ch2[]{"china"}; //相当于 char ch2[] "china"; 元素个数为6&#xff0c;默认会…