代码随想录--数组相关题目整理

news2025/1/10 10:57:35

LeetCode数组相关题目整理

1. LeetCode704 二分查找

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

解题思路:这道题就是典型的二分查找求解。关于二分查找以及对应的变种,查看我之前写的https://blog.csdn.net/lyx7762/article/details/128694594

/**
 * 搜索区间是左闭右闭的情况
 * @param nums
 * @param target
 * @return
*/
public int search(int[] nums, int target) {
    if (nums == null || nums.length == 0)
      return -1;
    // 这里使用的是左闭右闭区间
    int left = 0, right = nums.length - 1;
    // 对于左闭右闭区间 因为left == right 也是合法的,因此需要<=
    while (left <= right) {
        int mid = (left + right) / 2;
        if (nums[mid] > target) {
          // mid已经不满足条件,需要排出掉
          // 为什么要-1 而不是right = mid
          // 如果right=mid,那么实际上下一次的搜索区间为[left, mid]
          // 下一次搜索区间依然包含mid,而实际上mid已经不满足要求了
          right = mid - 1;
        } else if (nums[mid] < target) {
            left = mid + 1;
        } else {
            return mid;
        }
    }
    return -1;
}

2. LeetCode27 移除元素

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

数组的元素是不能删的,只能覆盖。

这个题需要注意的在数组中元素的删除实际上是通过覆盖来完成的

比如[1,2,3,4,5] 现在删除数组中4的元素,那么实际上是将4后面的元素都向前移动一个单位,把4覆盖掉,的到[1,2,3,5,5],返回的数组长度-1

解题思路1(暴力法):使用两个for循环。第一个循环用来循环遍历整个数组,第二个用来移动元素。

public int removeElement(int[] nums, int val) {
  if (nums == null || nums.length == 0)
      return 0;
  int size = nums.length;
  for (int i = 0; i < size; i++) {
      if (nums[i] != val)
        continue;

      for (int j = i; j < size - 1; j++) {
          nums[j] = nums[j + 1];
      }
      size--;
      i--; // 这个需要特别注意,因为我们覆盖元素,实际上就是将后面的元素都向前移动一位,那么i也要向前移动,否则会漏掉一些元素
  }
  return size;
}

解题思路2(利用快慢指针):首先需要明确快慢指针代表什么意思:

  • 快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组。
  • 慢指针:指向更新新数组下标的位置

快指针从头开始遍历数组,只要发现不等于给定val的元素,就将元素赋值为slow指针指向的位置。这样循环结束后,所有的不等于val的元素都保存起来

public int removeElement(int[] nums, int val) {
  if (nums == null || nums.length == 0)
      return 0;
  int fast = 0, slow = 0;
  for (fast = 0; fast < nums.length; fast++) {
      if (nums[fast] != val) {
          nums[slow] = nums[fast];
          slow++;
      }
  }
  return slow;
}

3. LeetCode997 有序数组平方

给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

示例 1: 输入:nums = [-4,-1,0,3,10] 输出:[0,1,9,16,100] 解释:平方后,数组变为 [16,1,0,9,100],排序后,数组变为 [0,1,9,16,100]

示例 2: 输入:nums = [-7,-3,2,3,11] 输出:[4,9,9,49,121]

解题思路1:采用暴力法。直接循环遍历整个数组,求出平方。然后调用数组排序函数即可。

public int[] sortedSquares(int[] nums) {
    if (nums == null || nums.length == 0)
        return null;
    for (int i = 0; i < nums.length; i++) {
        nums[i] *= nums[i];
    }
    Arrays.sort(nums);
    return nums;
}

解题思路2:利用双指针。因为数组本身是有序的,我们平方完以后,出现顺序不一样的原因只要是因为一些负数平方后可能大于本来的正数。根据分析可以发现,平方后数组最大的数字之可能出现在输入数组的左边或者右边(左边为最小的负数,那么平方后应该变的很大;右边为最大的正数,平方也可能很大)。

因此可以使用两个指针i, j,分别指向数组最左边和最右边的元素。另外创建一个和输入数组等大的数组

开始遍历数组,判断i, j指向的元素哪个平方最大,就保存到新数组的最后一个元素。依次类推,直到i>j位置

public int[] sortedSquares(int[] nums) {
    if (nums == null || nums.length == 0)
      return null;
    // 定义两个指针,分别指向数组的最左边和最右边
    int i = 0, j = nums.length - 1;

    // 创建结果数组
    int[] res = new int[nums.length];
    int k = j;

    while (i <= j) {
        int num1 = nums[i] * nums[i];
        int num2 = nums[j] * nums[j];
        if (num1 > num2) {
            res[k] = num1;
            k--;
            i++;
        } else {
            res[k] = num2;
            k--;
            j--;
        }
    }
    return res;
}

4. Leetcode209 长度最小的子数组

给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。

解题思路1(暴力法):使用两层for循环,第一层for循环负责子数组的起始位置,第二个for循环负责从起始位置开始依次遍历,依次求和,找到符合满足条件的子数组就break掉。

public int minSubArrayLen(int target, int[] nums) {
    if (nums == null || nums.length == 0) return 0;
    int min = Integer.MAX_VALUE;
    for (int i = 0; i < nums.length; i++) {
        // 如果一个元素就满足条件
        if (nums[i] >= target) return 1;

        int sum = nums[i], count = 1;
        for (int j = i + 1; j < nums.length; j++) {
            sum += nums[j];
            count++;
            if (sum >= target) {
                min = Integer.min(min, count);
                break; // 如果当前起始位置已经找到符合的了,就直接break,因为再往后找的不可能符合了
            }
        }
    }
    if (min == Integer.MAX_VALUE) return 0;
    return min;
}

解题思路2: 使用双指针实现的滑动窗口来解决。

  • 建立两个指针left, right,初始值都指向数组的第一个元素。其中left指向子数组的起始位置,right指向子数组的终止位置。
  • 使用right对数组进行循环遍历,每求出来一个元素,就进行累加,并判断是否满足条件。
  • 如果满足条件,则进入第二个while,从继续搜索最小的子数组。

采用这种方式,可以减少之间采用暴力法中很多累加求和的计算。

视频讲解地址:https://www.bilibili.com/video/BV1tZ4y1q7XE/

public int minSubArrayLen(int target, int[] nums) {
    if (nums == null || nums.length == 0) return 0;
    int min = Integer.MAX_VALUE;

    // 创建两个指针
    int left = 0, right = 0;
    int sum = 0;

    while (right < nums.length) {
        sum += nums[right];
        while (sum >= target) {
            min = Math.min(min, right - left + 1);
            sum -= nums[left];
            left++;
        }
        right++;
    }

    if (min == Integer.MAX_VALUE) return 0;
    return min;
}

我画了一个图来演示:

image-20230115175207813

这里需要注意while (sum >= target)我们使用了while而不是if。因为如果使用if,考虑下面的这种情况,返回的只是符合条件的子数组长度,但是不是最小的子数组长度。

image-20230115175342663

5. LeetCode59 螺旋矩阵II

给你一个正整数 n ,生成一个包含 1n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix

示例 1:

img

输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]

解题思路: 这个题首先要确定一共转几圈,然后确定每一圈的起始位置和终止位置。

转几圈:实际上转的圈数等于n/2,并且如果输入的n是奇数,那么转完n/2圈后,矩阵中心点元素还为空,因此需要手动赋值。

image-20230116194414707

每一次处理一条边,我们都是处理的左开右闭区间,这样,对于每一条边的处理方式是统一的。

image-20230116194936144

起始位置: 起始位置(0,0) (1,1)也就是起始位置每次都是上次上次起始位置+1

偏移量: 以上面的边为例,第一次遍历的区间的有边界是<n-1,第二次是n<n-2

此外,每遍历完一圈,起始位置和偏移量都需要+1

具体代码如下:

public int[][] generateMatrix(int n) {
    int[][] arr = new int[n][n];
    // 定义两个变量,用来记录每一圈的起始位置
    int startX = 0, startY = 0;
    // 定义一个计数器,用来实现给数组中元素赋值
    int count = 1;
    // 定义一个偏移量,因为我们处理矩阵中每一条边,都是按照左闭右开的处理方式
    // 而这个偏移量就是定义最后几个元素不处理,第一圈的时候就是最后一个元素不处理
    // 第二圈的时候就是最后两个元素不处理,以此类推
    int offset = 1;

    // 接下来就是开始循环,根据传入的n来计算需要转几圈 n / 2 = 转的圈数
    // 如果n是奇数,那么最后矩阵中最中间的元素需要单独赋值为n*n
    int loop = n / 2;
    while (loop > 0) {
        int col, row;
        // 首先填充上面的边
        for (col = startY; col < n - offset; col++) {
            // 填充数据 行不变,变的是列
            arr[startX][col] = count++;
        }
        // 填充右边的边
        for (row = startX; row < n - offset; row++) {
            // 填充数据 行变,列不变
            arr[row][col] = count++;
        }
        // 填充下面的边
        for (; col > offset - 1; col--) {
            // 行不变 列变
            arr[row][col] = count++;
        }
        // 填充左边的边
        for (; row > offset - 1; row--) {
            arr[row][col] = count++;
        }

        // 更新起始位置
        startX++;
        startY++;
        // 更新偏移量
        offset++;
        // 圈数减1
        loop--;
    }

    // 整个循环结束后,判断是否为奇数 如果为奇数,那么矩阵中中心点的值需要手动填充
    if (n % 2 == 1) {
      arr[n / 2][n / 2] = n * n;
    }
    return arr;
}

在这里插入图片描述

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

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

相关文章

亚马逊云科技助力游戏上云学习心得-运行篇

云服务已经是大势所趋了&#xff0c;通过购置传统服务器来进行应用开发&#xff0c;无法与现代化敏捷的开发方法相结合&#xff0c;对于系统运维的难度也大大增加&#xff0c;而云服务的弹性伸缩、动态计费可以很好地帮助中小企业实现快速应用开发&#xff0c;使得产品的价值最…

一文吃透python面向对象基础+进阶

目录基本理论面向过程与面向对象面向过程面向对象基本概念面向对象基本语法定义类创建对象属性属性和变量区别对象属性类属性限制对象属性添加方法实例方法类方法静态方法私有属性只读属性私有方法魔法方法字符串表示可调用索引操作切片操作比较操作布尔判断遍历操作面向对象三…

字节青训营Go语言学习第一天--基础语言+实战案例

文章目录走进Go语言基础语言2.2基础语言-变量2.3基础语法- if else2.4基础语法-循环基础语法-switch基础语法-数组基础语法-切片基础语法-map基础语法-range基础语法-函数基础语法-指针基础语法-结构体基础语法-结构体方法基础语法-错误处理基础语法-字符串操作基础语法-字符串…

通讯录升级--可增容(动态增长空间)

通讯录成员的改变 之前我们定义了date[100]的数组用来存放100个人的信息&#xff0c;但是当需要存储的人数超过100时&#xff0c;内存不够&#xff0c;存储人数较少时&#xff0c;又有些浪费&#xff0c;并且数组空间在创建时就已经确立&#xff0c;无法随需求改变&#xff0c…

rabbitmq+netcore6 【6】RPC:远程过程调用

文章目录1&#xff09;前言2&#xff09;Client interface 客户接口3&#xff09;Callback queue回调队列4&#xff09;Correlation Id 关联Id5&#xff09;Summary总结6&#xff09;综合以上代码准备工作服务端客户端结果验证官网参考链接&#xff1a; https://www.rabbitmq.c…

372. 超级次方

372. 超级次方题目算法设计&#xff1a;迭代算法设计&#xff1a;递归题目 传送门&#xff1a;https://leetcode.cn/problems/super-pow/ 题目不难懂&#xff0c;问题在于 b 是一个非常非常大的数&#xff0c;会溢出。 迭代和递归&#xff0c;各有解决方法&#xff0c;记录在…

Elasticsearch入门——kibanna和postman操作Elasticsearch索引示例

目录一、使用kibanna操作Elasticsearch索引示例二、使用postman操作Elasticsearch索引示例三、kibanna和postman操作Elasticsearch的总结一、使用kibanna操作Elasticsearch索引示例 启动Elasticsearch和kibanna服务&#xff0c;浏览器访问http://localhost:5601/,进入Dev Tools…

week11

T1汤姆斯的天堂梦 题目描述 汤姆斯生活在一个等级为 000 的星球上。那里的环境极其恶劣&#xff0c;每天 121212 小时的工作和成堆的垃圾让人忍无可忍。他向往着等级为 NNN 的星球上天堂般的生活。 有一些航班将人从低等级的星球送上高一级的星球&#xff0c;有时需要向驾驶…

【C语言】数据结构基础(每日小细节025),有三数之和哦

算法好题初阶&#xff08;一共14回已经更新完毕&#xff09;&#xff0c;从今天开始就是基础的数据结构题目 1.只出现一次的数字 如果不额外开辟任何空间的话一定要想到位运算符 异或^ :两个整数异或&#xff0c;遵循相同为0&#xff0c;相异为1的二进制位运算规则 &#x…

【Nginx 基础】

Nginx 的安装 Nginx 的静态网站部署 理解 Nginx 的反向代理与负载均衡&#xff0c;能够配置反向代理与负载均衡 一、 Nginx 概述 Nginx 是一款高性能的 HTTP 服务器/反向代理服务器及电子邮件&#xff08;IMAP/POP3&#xff09;代理服务器&#xff0c;由俄罗斯的程序工程师伊戈…

spring学习系列

Spring_三种方式的依赖注入1.第一种&#xff0c;set方式&#xff0c;property2.构造器注入&#xff08;构造方法&#xff09;3.p命名空间注入4、注入各种数据类型//老师类 public class Teacher {private String name;private int age; }//课程类 public class Course {private…

云原生技术学习笔记(基础版)

一、容器基本概念容器运行时&#xff0c;多种虚拟化技术&#xff0c;runC、kata、gVisor等。containerd -shim不是个lib&#xff0c;是个守护进程&#xff0c;管理容器生命周期,可被containerd动态接管。&#xff08;可以从containerd中脱离出来&#xff0c;插件化管理&#xf…

jvm系列(1)--JVM和Java体系架构

目录Java-跨平台的语言JVM-跨语言的平台多语言混合编程虚拟机虚拟机概念Java虚拟机JVM的位置JVM的整体结构Java代码执行流程JVM的架构模型基于栈的指令集架构基于寄存器的指令级架构两种架构的举例JVM架构总结JVM的生命周期虚拟机的启动虚拟机的执行虚拟机的退出Java-跨平台的语…

VTK-vtkSelectPolyDataFilter

前言&#xff1a;本博文主要记录vtkSelectPolyDataFilter接口的应用&#xff0c;实现原理&#xff0c;以及与其近似的vtkClipPolyData&vtkImplicitSelectionLoop的应用相比较&#xff0c;帮助小伙伴理解vtkSelectPolyDataFilter接口的实现原理&#xff0c;并且与其它接口进…

2023新生个人训练赛第08场解题报告

问题 A: Candies 题目描述 We have a 2N grid. We will denote the square at the i-th row and j-th column (1≤i≤2, 1≤j≤N) as (i,j). You are initially in the top-left square, (1,1). You will travel to the bottom-right square, (2,N), by repeatedly moving ri…

鉴源论坛 · 观通丨轨交系统安全性设计

作者 | 刘艳青 上海控安安全测评中心安全测评部测试经理 版块 | 鉴源论坛 观通 引语&#xff1a;第一篇对轨交信号系统从铁路系统分类和组成、城市轨交系统分类和组成、城市轨交系统功能、城市轨交系统发展方面做了介绍&#xff0c;第二篇从信号基础出发&#xff0c;讲述了信…

【蓝桥杯算法 1】AcWing166.飞行员兄弟

本文已收录专栏 &#x1f332;《蓝桥杯周训练》&#x1f332; “飞行员兄弟”这个游戏&#xff0c;需要玩家顺利的打开一个拥有 16 个把手的冰箱。 已知每个把手可以处于以下两种状态之一&#xff1a;打开或关闭。 只有当所有把手都打开时&#xff0c;冰箱才会打开。 把手可…

支持数位板的远程软件,实现远程使用 Wacom 数位板

现在数位板越来越流行了&#xff0c;影视、动漫、游戏、设计等行业经常需要用到。Wacom 是数位板领域的全球领导者&#xff0c;其设备为创意人员带来了真正的纸感绘图体验。 数位板用户需要远程办公的时候&#xff0c;经常会遇到两个问题&#xff1a;远程软件不支持数位板、远…

(考研湖科大教书匠计算机网络)第一章概述-第五节1:计算机网络体系结构之分层思想和举例

文章目录一&#xff1a;计算机网络结构分层的必要性&#xff08;1&#xff09;分层思想&#xff08;2&#xff09;计算机网络分层思想①&#xff1a;如何让两台计算机通过网线传输数据②&#xff1a;如何让分组在单个网络内传输③&#xff1a;如何让分组在网络间传输④&#xf…

SpringBoot项目练习

项目名称&#xff1a;旅游网站后台管理一&#xff1a;项目简介旅游网站后台管理,包括如下用户&#xff1a;旅游线路&#xff1a;线路图片&#xff1a;线路分类&#xff1a;旅行社&#xff1a;后台技术&#xff1a;springboot、mybatis、mybatis plus前台&#xff1a;bootstrap、…