代码随想录day01--数组

news2025/1/9 1:20:33

两数之和

题目

地址:https://leetcode.cn/problems/two-sum/

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。

示例:

给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9

所以返回 [0, 1]

代码(核心代码模式)

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int res[] = new res[2];
        if(nums == null || nums.length == 0){
            return res;
        }
        Map<Integer,Integer> map = new HashMap<>();
        for(int i=0;i<nums.length;i++){
            int temp = target - nums[i];
            if(map.containsKey(temp)){
                res[0] = map.get(temp);
                res[1] = i;
                break;
            }
            map.put(nums[i],i);
        }
        return res;
    }
}

二分查找

题目

地址:https://leetcode.cn/problems/binary-search/

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

二分查找最关键的是要找到边界条件:即分为两种边界一种是左闭右闭区间,一种是左闭右开区间、

而针对第一种情况,left == right是有意义的,因此在定义right时,是right = nums.length - 1;并且在循环条件里要使用while(left<=right)

在这里插入图片描述

而第二种情况:left == right是每有意义的,因此在定义right时,是right = nums.length;并且在循环条件里要使用while(left<right):即下一个目标值不会进行比较

在这里插入图片描述

代码

  1. 使用左闭右闭区间方法
class Solution {
    public int search(int[] nums, int target) {
        //先进行防御性编程
        if(target < nums[0] || target > nums[nums.length - 1]){
            return -1;
        }
        int left = nums[0],right = nums.length-1;
        while(left <= right){
            int mid = (left + (right-left >> 1));
            if(nums[mid] == target){
                return mid;
            }else if(nums[mid] > target){
                right = mid - 1 ;
            }else {
                left = mid + 1;
            }
        }
        return -1;
    }
}

2.使用左闭右开区间方法

class Solution {
    public int search(int[] nums, int target) {
        //先进行防御性编程
        if(target < nums[0] || target > nums[nums.length - 1]){
            return -1;
        }
        int left = nums[0],right = nums.length;
        while(left < right){
            int mid = (left + (right-left >> 1));
            if(nums[mid] == target){
                return mid;
            }else if(nums[mid] > target){
                right = mid;
            }else {
                left = mid + 1;
            }
        }
        return -1;
    }
}

移除元素

题目

地址:https://leetcode.cn/problems/remove-element/

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。

代码

使用双指针方法可以快速移除元素,在数组中内存空间是连续的,因此不是删除元素而是覆盖元素

使用双指针同向法

class Solution {
    public int removeElement(int[] nums, int val) {
        int slowIndex = 0;
        for(int fastIndex = 0; fastIndex<nums.length;fastIndex++){
            if(nums[fastIndex] != val){
                nums[slowIndex] = nums[fastIndex];
                slowIndex++;
            }
        }
        return slowIndex;
    }
}

使用双指针相向法

class Solution {
    public int removeElement(int[] nums, int val) {
        int leftIndex = 0,rightIndex = nums.length - 1;
        while(leftIndex <= rightIndex){
            if(nums[leftIndex] == val){
                nums[leftIndex] = nums[rightIndex];
                rightIndex--;
            }else{
                leftIndex++;
            }
        }
        return leftIndex;
    }
}

有序数组的平方

题目

地址:https://leetcode.cn/problems/squares-of-a-sorted-array/

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

最基本的排序就可以完成

双指针 也是很好的选择:

数组其实是有序的, 只不过负数平方之后可能成为最大数了。

那么数组平方的最大值就在数组的两端,不是最左边就是最右边,不可能是中间。

此时可以考虑双指针法了,i指向起始位置,j指向终止位置。

定义一个新数组result,和A数组一样的大小,让k指向result数组终止位置。

如果A[i] * A[i] < A[j] * A[j] 那么result[k--] = A[j] * A[j];

如果A[i] * A[i] >= A[j] * A[j] 那么result[k--] = A[i] * A[i];

如动画所示:

img

代码

使用最简单的排序算法就可以实现

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

使用双指针算法也可以实现

class Solution {
    public int[] sortedSquares(int[] nums) {
        int left = 0,right = nums.length - 1;
        int[] Result = new int[nums.length];
        int index = Result.length - 1;
        while(left<=right){
            if(nums[left]*nums[left]<nums[right]*nums[right]){
                Result[index--] = nums[right]*nums[right];
                --right;
            }else{
                Result[index--] = nums[left]*nums[left];
                ++left;
            }
        }
        return Result;
    }
}

长度最小的子数组

题目

地址:https://leetcode.cn/problems/minimum-size-subarray-sum/

给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。

思路就是使用滑动窗口来解决

209.长度最小的子数组

代码

class Solution {
     public int minSubArrayLen(int target, int[] nums) {
         int left = 0,sum = 0;//窗口的左边界和总和值
         int result = Integer.MAX_VALUE;
         for(int right=0;right<nums.length;right++){
             sum+=nums[right];
             while(sum>=target){
                 result = Math.min(result,right-left+1);
                 sum = sum - nums[left++];
             }
         }
         return result == Integer.MAX_VALUE ? 0:result;
     }
}

螺旋矩阵II

题目

地址:https://leetcode.cn/problems/spiral-matrix-ii/

给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。

示例:

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

模拟顺时针画矩阵的过程:

  • 填充上行从左到右
  • 填充右列从上到下
  • 填充下行从右到左
  • 填充左列从下到上

由外向内一圈一圈这么画下去。

这里一圈下来,我们要画每四条边,这四条边怎么画,每画一条边都要坚持一致的左闭右开,或者左开右闭的原则,这样这一圈才能按照统一的规则画下来。

那么我按照左闭右开的原则,来画一圈,大家看一下:

img

代码

class Solution {
    public int[][] generateMatrix(int n) {
        int[][] nums = new int[n][n];
        int loop = 1;//记录当前的圈数
        int x=0,y=0;//记录起始位置
        int offset = 1;//处理边界情况
        int i,j,count = 1;//行和列
        while(loop <= n/2){
            //从顶部开始螺旋
            for(j=y;j<n-offset;j++){
                nums[x][j] = count++;
            }

            //从右侧开始螺旋
            for(i=x;i<n-offset;i++){
                nums[i][j] = count++;
            }

            //从底部开始螺旋
            for(;j>y;j--){
                nums[i][j] = count++;
            }

            //从左侧开始
            for(;i>x;i--){
                nums[i][j] = count++;
            }
            loop++;
            x++;
            offset++;
            y++;
        }

        if(n % 2 == 1){
            nums[x][y] = count;
        }
        
        return nums;
    }
}

区间和

题目

题目描述

给定一个整数数组 Array,请计算该数组在每个指定区间内元素的总和。

输入描述

第一行输入为整数数组 Array 的长度 n,接下来 n 行,每行一个整数,表示数组的元素。随后的输入为需要计算总和的区间,直至文件结束。

输出描述

输出每个指定区间内元素的总和。

输入案例:

5
1
2
3
4
5
0 1
1 3

输出案例:

3
9

思路:前缀和 在涉及计算区间和的问题时非常有用

前缀和的思路其实很简单,我给大家举个例子很容易就懂了。

例如,我们要统计 vec[i] 这个数组上的区间和。

我们先做累加,即 p[i] 表示 下标 0 到 i 的 vec[i] 累加 之和。

如图:

img

如果,我们想统计,在vec数组上 下标 2 到下标 5 之间的累加和,那是不是就用 p[5] - p[1] 就可以了。

为什么呢?

p[1] = vec[0] + vec[1];
p[5] = vec[0] + vec[1] + vec[2] + vec[3] + vec[4] + vec[5];
p[5] - p[1] = vec[2] + vec[3] + vec[4] + vec[5];

这不就是我们要求的 下标 2 到下标 5 之间的累加和吗。

如图所示:
在这里插入图片描述

p[5] - p[1] 就是 红色部分的区间和。

而 p 数组是我们之前就计算好的累加和,所以后面每次求区间和的之后 我们只需要 O(1) 的操作。

特别注意: 在使用前缀和求解的时候,要特别注意 求解区间。

如上图,如果我们要求 区间下标 [2, 5] 的区间和,那么应该是 p[5] - p[1],而不是 p[5] - p[2]。

代码

import java.util.Scanner;

/**
 * @author: dlwlrma
 * @data 2024年11月29日 19:39
 * @Description 区间和算法
 */
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int n =sc.nextInt();
        int[] vec = new int[n];
        int[] p = new int[n];

        int presum = 0;
        for (int i = 0; i < n; i++) {
            vec[i] = sc.nextInt();
            presum += vec[i];
            p[i] = presum;
        }

        while(sc.hasNext()){
            int a = sc.nextInt();
            int b = sc.nextInt();

            int sum;
            if(a == 0){
                sum = p[b];
            }else{
                sum = p[b] - p[a-1];
            }
            System.out.println(sum);
        }
        sc.close();
    }
}



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

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

相关文章

Webpack前端工程化进阶系列(二) —— HMR热模块更新(图文+代码)

前言 之前更新过一篇Webpack文章:Webpack入门只看这一篇就够了(图文代码)&#xff0c;没想到颇受好评&#xff0c;很快就阅读量就破万了hhh&#xff0c;应读者私信的要求&#xff0c;决定继续更新Webpack进阶系列的文章&#xff01; 进入今天的主题 —— HMR 热模块替换(HotM…

Flink的双流join理解

如何保证Flink双流Join准确性和及时性、除了窗口join还存在哪些实现方式、究竟如何回答才能完全打动面试官呢。。你将在文中找到答案。 1 引子 1.1 数据库SQL中的JOIN 我们先来看看数据库SQL中的JOIN操作。如下所示的订单查询SQL&#xff0c;通过将订单表的id和订单详情表ord…

【MYSQL数据库相关知识介绍】

MySQL 在我们日常技术中是一个广泛使用的开源关系型数据库管理系统&#xff0c;所以作为测试同学&#xff0c;掌握mysql的相关知识是必不可少的技能之一&#xff0c;所以小编从软件测试的角色出发&#xff0c;来整理一些跟测试相关的知识&#xff0c;希望能够帮助到大家。 一、…

数组和链表OJ题

leetcode用编译器调试的技巧 数组和链表练习题 leetcode/reverse_Link/main.c Hera_Yc/bit_C_学习 - 码云 - 开源中国 1、移除元素 ​​​​​​27. 移除元素 - 力扣&#xff08;LeetCode&#xff09; int removeElement(int* nums, int numsSize, int val) {int src 0, …

云服务器架构有什么区别?X86计算、Arm、GPU/FPGA/ASIC和裸金属全解析

阿里云服务器ECS架构有什么区别&#xff1f;X86计算、Arm计算、GPU/FPGA/ASIC、弹性裸金属服务器和高性能计算有什么区别&#xff1f;x86架构是最常见的&#xff0c;CPU采用Intel或AMD处理器&#xff1b;ARM架构具有低功耗的特性&#xff0c;CPU采用Ampere Altra / AltraMax或阿…

泽众TestCenter测试管理工具之案例库,提升测试工作的效率和质量

在当今的软件开发生命周期中&#xff0c;测试管理工具扮演着至关重要的角色。泽众TestCenter测试管理工具&#xff08;简称TC&#xff09;&#xff0c;作为一款广受好评的测试管理工具&#xff0c;凭借其强大的案例库功能&#xff0c;极大地提升了测试工作的效率和质量。 案例库…

Spring Cloud(Kilburn 2022.0.2版本)系列教程(五) 服务网关(SpringCloud Gateway)

Spring Cloud(Kilburn 2022.0.2版本)系列教程(五) 服务网关(SpringCloud Gateway) 一、服务网关 1.1 什么是网关 在微服务架构中&#xff0c;服务网关是一个至关重要的组件。它作为系统的入口&#xff0c;负责接收客户端的请求&#xff0c;并将这些请求路由到相应的后端服务…

基于单片机的多功能宠物窝的设计

本设计以STM32主控制器为核心芯片&#xff0c;它的组成元件有电机、温度传感器、时钟模块等。温度传感器的作用是采集环境温度的数据&#xff0c;时钟模块的作用是采集时间。将具体数据进行收集以后&#xff0c;主控制器将所有相关数据予以处理&#xff0c;从而将有关信息传递到…

Windows搭建MaskRCNN环境

环境&#xff1a;python3.6 1. 在miniconda上创建虚拟环境 miniconda下载地址&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda # 创建环境 conda create -n maskrcnn python3.6 # 激活 maskrcnn 环境&#xff0c;后续操作都在这个环境下进行 conda ac…

LLM PPT Translator

LLM PPT Translator 引言Github 地址UI PreviewTranslated Result Samples 引言 周末开发了1个PowerPoint文档翻译工具&#xff0c;上传PowerPoint文档&#xff0c;指定想翻译的目标语言&#xff0c;通过LLM的能力将文档翻译成目标语言的文档。 Github 地址 https://github.…

新质驱动·科东软件受邀出席2024智能网联+低空经济暨第二届湾区汽车T9+N闭门会议

为推进广东省加快发展新质生产力&#xff0c;贯彻落实“百县千镇万村高质量发展工程”&#xff0c;推动韶关市新丰县智能网联新能源汽车、低空经济与数字技术的创新与发展&#xff0c;充分发挥湾区汽车产业链头部企业的带动作用。韶关市指导、珠三角湾区智能网联新能源汽车产业…

Zookeeper选举算法与提案处理概览

共识算法(Consensus Algorithm) 共识算法即在分布式系统中节点达成共识的算法&#xff0c;提高系统在分布式环境下的容错性。 依据系统对故障组件的容错能力可分为&#xff1a; 崩溃容错协议(Crash Fault Tolerant, CFT) : 无恶意行为&#xff0c;如进程崩溃&#xff0c;只要…

实例讲解MATLAB绘图坐标轴标签旋转

在进行绘图时需要在图片上添加上做标轴的标签&#xff0c;但是当数据量比较多时&#xff0c;例如一天24小时的数据&#xff0c;这时把每个小时显示在左边轴的标签上&#xff0c;文字内容放不下&#xff0c;因此需要将坐标轴标签旋转一定的角度&#xff0c;这样可以更好在图形上…

flutter项目AndroidiOS自动打包脚本

从业数年余,开发出身,经数载努力位项目经理,因环境欠佳,终失业.失业达七月有余,几经周转,现又从开发,既回原点亦从始.并非与诸位抢食,仅为糊口,望海涵!因从头开始,所经之处皆为新奇,遂处处留痕以备日后之需. 自动打包脚本原文地址:https://zhuanlan.zhihu.com/p/481472311 转…

免费实用在线AI工具集合 - 加菲工具

免费在线工具-加菲工具 https://orcc.online/ sql格式化 https://orcc.online/tools/sql 时间戳转换 https://orcc.online/tools/timestamp Base64 编码解码 https://orcc.online/tools/base64 URL 编码解码 https://orcc.online/tools/url Hash(MD5/SHA1/SHA256…) 计算 h…

Scala学习记录,统计成绩

统计成绩练习 1.计算每个同学的总分和平均分 2.统计每个科目的平均分 3.列出总分前三名和单科前三名&#xff0c;并保存结果到文件中 解题思路如下&#xff1a; 1.读入txt文件&#xff0c;按行读入 2.处理数据 &#xff08;1&#xff09;计算每个同学的总分平均分 import s…

第六届机器人、智能控制与人工智能国际(RICAI 2024)

会议信息 会议时间与地点&#xff1a;2024年12月6-8日&#xff0c;中国南京 会议官网&#xff1a;www.ic-ricai.org &#xff08;点击了解大会参会等详细内容&#xff09; 会议简介 第六届机器人、智能控制与人工智能国际学术会议&#xff08;RICAI 2024&#xff09;将于20…

分布式协同 - 分布式锁一二事儿

文章目录 导图Pre概述概述1. 分布式互斥和临界资源的协调2. 分布式锁的基本原理3. 分布式锁的实现方式a. 基于数据库实现的分布式锁b. 基于Redis实现的分布式锁c. 基于Zookeeper实现的分布式锁 4. 高并发场景下的分布式锁优化a. 分段锁&#xff08;Sharded Locks&#xff09;b.…

Stripe测试

通过官方提供的Stripe-cli工具进行测试。 1. 下载Stripe-cli 下载链接&#xff1a;Release v1.17.1 stripe/stripe-cli GitHub 2. 获取密钥 进入到stripe控制台测试模式 查看API密钥 3. 测试 指定您的API 私钥 stripe login --api-key sk_test_51ISwaXTwNwO1Rvw32DNG10…

Laravel8.5+微信小程序实现京东商城秒杀方案

一、商品秒杀涉及的知识点 鉴权策略封装掊口访问频次限制小程序设计页面防抖接口调用订单创建事务使用超卖防御 二、订单库存系统方案&#xff08;3种&#xff09; 下单减库存 优点是库存和订单的强一致性&#xff0c;商品不会卖超&#xff0c;但是可能导致恶意下单&#xff…