day54【代码随想录】二刷数组

news2024/11/16 9:41:44

文章目录

  • 前言
  • 一、二分查找(力扣724)
  • 二、移除元素(力扣27)【双指针】
  • 三、有序数组的平方(力扣977)【双指针】
  • 四、合并两个有序数组(力扣88)
  • 五、长度最小的子数组(力扣209)【滑动窗口】
  • 六、水果成篮(力扣904)【滑动窗口】****
  • 七、最小覆盖子串(力扣76)【滑动窗口】****
  • 八、最大连续1的个数 III(力扣1004)【滑动窗口】
  • 九、无重复字符的最长子串(力扣3)【滑动窗口】****
  • 总结


前言

1、二分查找
2、移除元素
3、有序数组的平方
4、合并两个有序数组
5、长度最小的子数组
6、水果成篮
7、最小覆盖字串
8、最大连续1的个数|||
9、无重复字符的最长字串


一、二分查找(力扣724)

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
在这里插入图片描述

class Solution {
    public int search(int[] nums, int target) {
        int left;
        int right;
        int mid;
        int index = -1;
        left = 0;
        right = nums.length-1;
        while(left<=right){
            mid = (left+right)/2;
            if(nums[mid]>target){
                right=mid-1;
            }else if(nums[mid]<target){
                left=mid+1;
            }else if (nums[mid]==target){
                return mid;
            }
        }
        return index;    
    }
}

二、移除元素(力扣27)【双指针】

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
在这里插入图片描述

class Solution {
    public int removeElement(int[] nums, int val) {
        int fast;
        int slow;

        for(fast=0,slow=0; fast<nums.length;){
            if(nums[fast]==val){
                fast++;
            }
            else{
                nums[slow++] = nums[fast++];
            }
        }
        return slow;
    }
}

三、有序数组的平方(力扣977)【双指针】

有一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
在这里插入图片描述
暴力求解省略:
每个数平方之后,排个序,美滋滋
时间复杂度:O(n + nlogn),
请添加图片描述

class Solution {
    public int[] sortedSquares(int[] nums) {
        int[] res = new int[nums.length];
        int slow=0;
        int fast=nums.length-1;
        int index = nums.length-1;
        for(slow=0,fast=nums.length-1;slow<=fast;){
            if(nums[slow]*nums[slow]>=nums[fast]*nums[fast]){
                res[index--]=nums[slow]*nums[slow]; 
                slow++;
            }else{
                res[index--]=nums[fast]*nums[fast];
                fast--;
            }
        }
        return res;
    }
}

时间复杂度:O(n)

四、合并两个有序数组(力扣88)

给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。

请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。
在这里插入图片描述

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        int i = m-1;
        int j = n-1;
        int index = nums1.length-1;
        for(;j>=0;){
            if(i<0||nums1[i]<=nums2[j]){
                nums1[index--] = nums2[j];
                j--;
            }
            else{
                nums1[index--] = nums1[i];
                i--;
            }
        }
    }
}

注意要考虑边界条件:
在这里插入图片描述

五、长度最小的子数组(力扣209)【滑动窗口】

给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
在这里插入图片描述
暴力求解:
两个for循环,然后不断的寻找符合条件的子序列,时间复杂度很明显是O(n^2)。

		for (int i = 0; i < nums.length; i++) { // 设置子序列起点为i
            sum = 0;
            for (int j = i; j < nums.length; j++) { // 设置子序列终止位置为j
                sum += nums[j];
                if (sum >= s) { // 一旦发现子序列和超过了s,更新result
                    subLength = j - i + 1; // 取子序列的长度
                    result = result < subLength ? result : subLength;
                    break; // 因为我们是找符合条件最短的子序列,所以一旦符合条件就break
                }
            }

滑动窗口:
滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果
在暴力解法中,是一个for循环滑动窗口的起始位置,一个for循环为滑动窗口的终止位置,用两个for循环 完成了一个不断搜索区间的过程。那么滑动窗口用一个for循环来完成这个操作。

滑动窗口问题一:如果用一个for循环,那么应该表示 滑动窗口的起始位置,还是终止位置
滑动窗口问题二:如何遍历剩下的终止位置?
滑动窗口问题三:滑动窗口的起始位置如何移动?

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int left =0;
        int right;
        int subLength = Integer.MAX_VALUE;     
        int res=0;

        //滑动窗口一个for循环表示(滑动窗口终止位置)
        for(right=0;right<nums.length;right++){
            res+=nums[right];
            while(res>=target){
                subLength = Math.min(subLength,right-left+1);
                res -= nums[left++];
            }
        }
        return subLength == Integer.MAX_VALUE? 0:subLength;
    }
}

六、水果成篮(力扣904)【滑动窗口】****

fruits[i] 是第 i 棵树上的水果 种类 。
想要尽可能多地收集水果。然而,农场的主人设定了一些严格的规矩,你必须按照要求采摘水果:
只有 两个 篮子,并且每个篮子只能装 单一类型 的水果。每个篮子能够装的水果总量没有限制
你可以选择任意一棵树开始采摘,你必须从 每棵 树(包括开始采摘的树)上 恰好摘一个水果 。采摘的水果应当符合篮子中的水果类型。每采摘一次,你将会向右移动到下一棵树,并继续采摘
一旦走到某棵树前,但水果不符合篮子的水果类型,那么就必须停止采摘。
给你一个整数数组 fruits ,返回可以收集的水果的最大数目。

白话题意:求满足某个条件(数组值最多就两类的连续数组,例如[1,2,2,1,2])的最长数组长度
在这里插入图片描述

class Solution {
    public int totalFruit(int[] fruits) {
        HashMap<Integer,Integer> map = new HashMap<>();
        int res =0;
        int i=0;
        int j=0;
        while(j<fruits.length){
            //判断当前是否满足条件?
            map.put(fruits[j],map.getOrDefault(fruits[j],0)+1);

            while(map.size()>2){//不满足条件
                //把加进来i的都移出去
                map.put(fruits[i],map.get(fruits[i])-1);
                if(map.get(fruits[i])==0){
                    map.remove(fruits[i]);
                }
                i++;
            }
            //更新结果
            res = Math.max(res,j-i+1);
            j++;
        }
        return res;
    }
}

For me 比较考验map数组的使用

七、最小覆盖子串(力扣76)【滑动窗口】****

一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。

同样是滑动窗口,这两题有什么区别?区别在于904题求的是最大滑窗,而本题求的是最小滑窗
在这里插入图片描述

class Solution {
    public String minWindow(String s, String t) {
        //最小滑动窗口:

        int[] need = new int[128];
        //记录t中需要字符的个数
        for(int i =0; i<t.length();i++){
            need[t.charAt(i)]++;
        }
        int i=0;
        int j=0;
        String res = "";
        int count = t.length();
        int size = Integer.MAX_VALUE;
        int start =0;

        while(j<s.length()){
            //判断是否满足条件
           if(need[s.charAt(j)]>0){
                count--;
           }
           need[s.charAt(j)]--; //把右边字符加入窗口
           while(count==0){ //满足条件 窗口中已经包含所有元素
          // 一旦满足条件,尽可能的压缩i,并且不断更新结果
                //更新结果值
                while(i<j && need[s.charAt(i)]<0){ //压缩左窗口
                    need[s.charAt(i)]++;
                    i++;
                }
                if(j-i+1<size){
                    size = j-i+1;  //更新结果值
                    start = i;  //需要记录窗口的起始位置
                }
                need[s.charAt(i)]++;
                i++;
                count++;

           }
           j++;
        }
    return size == Integer.MAX_VALUE? "" :s.substring(start,start+size);
    }
}

窗口扩展时寻找可行解,窗口收缩时优化可行解。而且这个题可行解每次都是一个

八、最大连续1的个数 III(力扣1004)【滑动窗口】

给定一个二进制数组 nums 和一个整数 k,如果可以翻转最多 k 个 0 ,则返回 数组中连续 1 的最大个数 。
最大滑动窗口:

class Solution {
    public int longestOnes(int[] nums, int k) {
        int i =0;
        int j =0;
        int size = 0;
        int zeroCount =0;
        while(j<nums.length){ //滑动窗口终止位置
            //判断是否满足条件  把k个0翻转为1
            if(nums[j]==0 ){
                zeroCount++;
            }

            //不满足条件:
            while(zeroCount>k){//缩小左边界,一旦左边界满足 就退出循环,尽可能取到窗口的最大长度
                if(nums[i]==0){
                    zeroCount--;
                }
                i++;
            }
            //更新结果
            size = Math.max(size,j-i+1);
            j++;
        }
        return size;
    }
}

九、无重复字符的最长子串(力扣3)【滑动窗口】****

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
在这里插入图片描述
取滑动窗口最大值:

class Solution {
    public int lengthOfLongestSubstring(String s) {
        if(s.length()==0) return 0;
        //最大滑动窗口
        int i=0;
        int j=0;
        int size = 0;
        HashMap<Character,Integer> map = new HashMap<>();

        while(j<s.length()){
            if(map.containsKey(s.charAt(j))){ //看当前的字符串中是否有重复的
                i = Math.max(i,map.get(s.charAt(j))+1);
            }
            map.put(s.charAt(j),j);
            size = Math.max(size,j-i+1);
            j++;
        }
        return size;
    }
}

总结

滑动窗口模板:
来源:滑动窗口模板参考链接

最小滑窗模板:给定数组 nums,定义滑窗的左右边界 i, j,求满足某个条件的滑窗的最小长度。

while j < len(nums):
    判断[i, j]是否满足条件
    while 满足条件:
        不断更新结果(注意在while内更新!)
        i += 1 (最大程度的压缩i,使得滑窗尽可能的小)
    j += 1

最大滑窗模板:给定数组 nums,定义滑窗的左右边界 i, j,求满足某个条件的滑窗的最大长度。

while j < len(nums):
    判断[i, j]是否满足条件
    while 不满足条件:
        i += 1 (最保守的压缩i,一旦满足条件了就退出压缩i的过程,使得滑窗尽可能的大)
    不断更新结果(注意在while外更新!)
    j += 1

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

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

相关文章

前端学习第二阶段-第3章 Flex 伸缩布局

3-1 移动端基础知识 01-移动端基础 02-视口 03-meta视口标签 04-物理像素与物理像素比 05-二倍图 06-背景缩放background-size 07-背景二倍图以及多倍图切图 08-移动端开发选择 09-移动端技术解决方案 10-移动端特殊样式 11-移动端技术选型 12-流式布局 3-2 移动端电商首页制作…

Python基础—while循环

(1)while循环&#xff1a; 语法格式&#xff1a; while 条件&#xff1a;   执行语句1……   执行语句2…… 适用条件&#xff1a;无限循环 死循环 while True:print(条件是真的&#xff01;)代码实例&#xff1a; i 0 # 创建一个计数的变量 while i < 5: # Truepr…

感知趋势,洞察发展:2023(第十届)趋势与预测大会成功举办

2023年2月23日&#xff0c;运联年会&#xff1a;2023&#xff08;第十届&#xff09;趋势与预测大会在深圳机场凯悦酒店成功闭幕。自2014年开始&#xff0c;“运联年会&#xff1a;趋势与预测”已经连续举办九届。这场大会&#xff0c;既是一次行业性的“年终总结”&#xff0c…

【Java开发】JUC基础 01:进程、线程、多线程

1 进程与线程1.1 进程开发写的代码称为程序&#xff0c;那么我们将程序运行起来&#xff0c;我们称之为进程&#xff1b;进程就是申请一块内存空间&#xff0c;将数据放到内存空间中去&#xff0c;是系统进行资源分配和调度的基本单位。&#x1f4cc; 程序与进程的区别程序是数…

QML Item

在QML中所有的可视项目都继承自Item&#xff0c;虽然Item本身没有可视化的外观&#xff0c;但它定义了可视化项目的所有属性。 Item可以作为容器使用&#xff1a; Item{Rectangle{id:retc}Rectangle{id:retc1}Rectangle{id:retc2}Rectangle{id:retc3}} item拥有children属性…

MyBatis学习笔记(七) —— 特殊SQL的执行

7、特殊SQL的执行 7.1、模糊查询 模糊查询的三种方式&#xff1a; 方式1&#xff1a;select * from t_user where username like ‘%${mohu}%’ 方式2&#xff1a;select * from t_user where username like concat(‘%’,#{mohu},‘%’) 方式3&#xff1a;select * from t_u…

DolphinScheduler跨版本升级1.3.8至3.0.1

DolphinScheduler跨版本升级1.3.8至3.0.1Refer背景基础环境依赖版本升级修改pom.xml问题解决MYSQL升级1.文件替换2.修改表结构t_ds_process_definitiont_ds_alertt_ds_process_instance3.时间参数修改4.数据库升级DOLPHIN安装zookeeper集群创建用户dolphinscheduler_env.shinst…

指针变量作为函数参数详解,形参和实参之间的值传递如何传递?如何改变指针变量所指向的变量?

函数的参数不仅可以是整型&#xff0c;浮点型&#xff0c;字符型等数据&#xff0c;还可以是指针类型&#xff1b;它的作用是将一个变量的地址传送到另一个函数中。 关于地址&#xff0c;指针&#xff0c;指针变量可以参考我的上一篇文章&#xff1a; 地址&#xff0c;指针&…

线程的基本方法

线程等待&#xff1a;wait方法 调用wait方法的线程会进入WAITING状态&#xff0c;只有等到其他线程的通知或程序被中断才会返回。调用wait方法后会释放对象的锁&#xff0c;因此 wait方法一般被用于同步方法或同步代码块中 。 线程睡眠&#xff1a;sleep方法 调用sleep方法会导…

Spring Boot 版本升级2.2.11.RELEASE至2.7.4

2.2.11.RELEASE > 2.7.4项目更新spring-boot-starter-parent 主依赖&#xff0c;导致项目跑不起了日志也没有输出有用信息&#xff0c;自己查看源码调试启动入口打断点&#xff0c;一步步进入方法定位项目停止代码我的项目执行到SpringApplication.class 的152行代码会停止项…

华为HCIE学习之Openstack Glance组件(glance对接swift)

文章目录一、Glance的结构二、服务部署流程三、将glance存储在swift中1、默认使用swift来存储2、指定可以存在swift中3、swift版本4、keystone的endpoint地址&#xff08;当glance去找swift时通过keystone去找&#xff09;5、租户名:用户名&#xff0c;用户必须拥有admin角色6、…

【C语言】自定义类型:结构体、枚举、联合

目录 1.结构体 1.1结构体类型 1.2结构体的自引用 1.3结构体的初始化 1.4结构体内存对齐 //对齐 //offsetof //修改默认对齐数 1.5结构体传参 2.位段 2.1位段的内存开辟 2.2位段的内存分配 3.枚举 4.联合&#xff08;共用体&#xff09; //判断大小端 1.结构体…

【GO】k8s 管理系统项目23[前端部分–工作负载-Pod]

k8s 管理系统项目[前端部分–工作负载-Deployment] 1. 代码部分 1.1 准备工作 由于Pod页面和Deployment内容差不多.那么就直接把Deployment的内容复制过来.再做修改. 替换Deployment为Pod替换Deploy为Pod替换deployment为pod替换deploy为pod禁用新增的按钮,删除新增方法,表…

django后端服务、logstash和flink接入VictoriaMetrics指标监控

0.简介 通过指标监控可以设置对应的告警&#xff0c;快速发现问题&#xff0c;并通过相应的指标定位问题。 背景&#xff1a;使用的 VictoriaMetrics(简称 VM) 作为监控的解决方案&#xff0c;需要将 django 服务、logstash 和 flink 引擎接入进来&#xff0c;VM 可以实时的获…

SpringBoot:SpringBoot配置文件.properties、.yml 和 .ymal(2)

SpringBoot配置文件1. 配置文件格式1.1 application.properties配置文件1.2 application.yml配置文件1.3 application.yaml配置文件1.4 三种配置文件优先级和区别2. yaml格式2.1 语法规则2.2 yaml书写2.2.1 字面量&#xff1a;单个的、不可拆分的值2.2.2 数组&#xff1a;一组按…

操作系统权限提升(十八)之Linux提权-内核提权

Linux 内核提权 Linux 内核提权原理 内核提权是利用Linux内核的漏洞进行提权的&#xff0c;内核漏洞进行提权一般包括三个环节&#xff1a; 1、对目标系统进行信息收集&#xff0c;获取到系统内核信息及版本信息&#xff1b; 2、根据内核版本获取其对应的漏洞以及EXP 3、使…

第七届蓝桥杯省赛 C++ A/B组 - 四平方和

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 &#x1f4da;专栏地址&#xff1a;蓝桥杯题解集合 &#x1f4dd;原题地址&#xff1a;四平方和 &#x1f4e3;专栏定位&#xff1a;为想参加蓝桥杯的小伙伴整理常考算法题解&#xff0c;祝大家…

Docker简介与用法

文章目录1、Docker简介1.1、Docker能解决什么问题1.2、什么是虚拟机技术1.2.1、虚拟机的缺点1.3、什么是容器1.3.1、容器与虚拟机比较1.4、分析 Docker 容器架构1.4.1、Docker客户端和服务器1.4.2、Docker 镜像(Image)1.4.3、Docker 容器(Container)1.4.4、Docker 仓库(reposit…

Windows程序员学习Linux环境内存管理

我是荔园微风&#xff0c;作为一名在IT界整整25年的老兵&#xff0c;今天我们来重新审视一下Windows程序员如何学习Linux环境内存管理。由于很多程序在Windows环境下开发好后&#xff0c;还要部署到Linux服务器上去&#xff0c;所以作为Windows程序员有必要学习Linux环境的内存…

【计算机三级网络技术】 第三篇 IP地址规划技术

IP地址规划技术 文章目录IP地址规划技术一、IP 地址规划以及划分地址新技术1.IP地址的标准分类&#xff08;第一阶段&#xff09;2.划分子网的三级地址结构(第二阶段)3.构成超网的无类域间路由技术(第三阶段)4.网络地址转换技术(第四阶段)二、IP 地址分类1.A类、B类与C类IP地址…