和数组处理有关的一些OJ题(JAVA)(ArrayList)

news2024/11/19 18:23:28

1、给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。 不要使用额外的数组空间,你必须确保时间复杂度为O(N),空间复杂度为O,并原地修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

力扣链接:27. 移除元素 - 力扣(Leetcode)

因为它这里要求的是直接在原数组上进行修改,那么我们可以通过双指针法来原地修改输入数组,来实现移除元素的操作。

1、使用两个指针 left 和 right,初始化为数组的起始位置。

2、当 right 指向的元素等于要移除的值 val 时,将 right 指针向右移动一位。

3、当 right 指向的元素不等于要移除的值 val 时,将 right 指向的元素复制到 left 指向的位置,并同时将 left 和 right 指针都向右移动一位。

4、重复步骤 2 和步骤 3,直到 right 指针超过数组的长度。

5、返回 left 指针的值,即为新的长度。

public class RemoveElement {
    public static int removeElement(int[] nums, int val) {
        int left = 0;
        int right = 0;

        while (right < nums.length) {
            if (nums[right] != val) {
                nums[left] = nums[right];
                left++;
            }
            right++;
        }

        return left;
    }

    public static void main(String[] args) {
        int[] nums = {3, 2, 2, 3};
        int val = 3;

        int newLength = removeElement(nums, val);

        System.out.println("New Length: " + newLength);
        System.out.print("Modified Array: ");
        for (int i = 0; i < newLength; i++) {
            System.out.print(nums[i] + " ");
        }
    }
}

其实总的来说就是:

右指针指向当前将要处理的元素,左指针指向下一个将要被赋值的位置。

如果右指针指向的元素不等于 val ,那么就代表它是我们最后数组里面保留的数字,我们就可以将右指针指向的元素赋值给左指针,然后将左右指针同时++;

如果右指针指向的元素等于 val ,那么我们就要把它覆盖掉,这个时候保持左指针不动,右指针继续右移去寻找下一个不等于 val 的值,如果找到,那么把那个数字赋值给我们左指针仍指向的这个等于 val 的数字,相当于把它覆盖掉了。如果没有找到,那么就遗留在数组的最后不用去管它,当左右指针遍历完输入数组以后,我们 left 的值就是输出数组的长度。

力扣的官方题解中还给出了一种效率更高的方法,这个方法避免了需要保留的元素的重复赋值操作(在原来的方法中,我们对需要保存下来的值也进行了一次从right到left赋值的操作): 

作者:力扣官方题解
链接:https://leetcode.cn/problems/remove-element/solutions/730203/yi-chu-yuan-su-by-leetcode-solution-svxi/

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

我们才学完 ArrayList ,可以试试使用 ArrayList 来实现移除元素的操作,尽管题目要求是原地修改输入数组,但是其实这里也是可以通过 ArrayList 辅助进行处理的。

import java.util.ArrayList;

public class RemoveElement {
    public static int removeElement(int[] nums, int val) {
        ArrayList<Integer> list = new ArrayList<>();

        // 将不等于 val 的元素添加到 ArrayList 中
        for (int num : nums) {
            if (num != val) {
                list.add(num);
            }
        }

        // 将 ArrayList 中的元素复制回原数组
        int newSize = list.size();
        for (int i = 0; i < newSize; i++) {
            nums[i] = list.get(i);
        }

        return newSize;
    }

    public static void main(String[] args) {
        int[] nums = {3, 2, 2, 3};
        int val = 3;

        int newLength = removeElement(nums, val);

        System.out.println("New Length: " + newLength);
        System.out.print("Modified Array: ");
        for (int i = 0; i < newLength; i++) {
            System.out.print(nums[i] + " ");
        }
    }
}

我们这里甚至把原数组的值也改变了,使之只包含我们需要的数据。

2、给你一个升序排列的数组 nums ,请你原地删除重复出现的元素,使每个元素只出现一次,返回删除后数组的新长度。元素的相对顺序应该保持一致 。然后返回 nums 中唯一元素的个数。

考虑 nums 的唯一元素的数量为 k,你需要做以下事情确保你的题解可以被通过:

更改数组 nums ,使 nums 的前 k 个元素包含唯一元素,并按照它们最初在 nums 中出现的顺序排列。 nums 的其余元素与 nums 的大小不重要。返回 k 。

例如;

输入:nums = [0,0,1,1,1,2,2,3,3,4]

输出:5, nums = [0,1,2,3,4]

解释:函数应该返回新的长度5.并且原数组 nums 的前五个元素被修改为【0,1,2,3,4】不需要考虑数组中超出新长度后面的元素。

力扣链接:26. 删除有序数组中的重复项 - 力扣(Leetcode) 

这一题有一个地方值得注意:这是一个有序的数组,所以如果有重复元素,那么它们一定是相邻的,我们仍然可以沿用刚刚的双指针方法:

    public int removeDuplicates(int[] nums) {
        int left = 0;
        int right = 0;
        while (right < nums.length) {
            if (nums[left] == nums[right]) {
                right++;
            } else {
                if (nums[right] != nums[left + 1]) {
                    nums[left + 1] = nums[right];
                }
                left++;
                right++;
            }
        }
        return left + 1;
    }

3、给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。
请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。

注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。

对于这道题,如果要在不使用额外空间的情况下合并两个有序数组,我们可以考虑从后向前进行合并,避免元素的频繁移动。所以我们还是可以使用双指针法来完成:

1、初始化指针 p1,指向 nums1 的第一个元素,指针 p2,指向 nums2 的第一个元素。

2、创建一个临时数组 merged,用于存储合并后的数组。

3、比较 nums1[p1] 和 nums2[p2] 的值,将较小的值添加到 merged 数组中,并将对应指针向后移动一位。

4、重复步骤 3,直到其中一个数组的所有元素都添加到 merged 数组中。

5、将剩余的数组中的元素添加到 merged 数组中,如果是 nums1 数组剩余元素,无需处理;如果是 nums2 数组剩余元素,则直接复制到 merged 数组中。

6、将 merged 数组中的元素复制回 nums1 数组中。

 public void merge(int[] nums1, int m, int[] nums2, int n) {
        int p1 = m - 1;
        int p2 = n - 1;
        int p = m + n - 1;

        while (p1 >= 0 && p2 >= 0) {
            if (nums1[p1] > nums2[p2]) {
                nums1[p] = nums1[p1];
                p1--;
            } else {
                nums1[p] = nums2[p2];
                p2--;
            }
            p--;
        }

        // 将 nums2 中剩余的元素合并到 nums1 中
        while (p2 >= 0) {
            nums1[p] = nums2[p2];
            p2--;
            p--;
        }
    }

这种方法只使用了常量级的额外空间,符合题目要求的空间复杂度为 O(1),同时也满足题目要求的将合并后的数组存储在 nums1 中。

如果用上了 ArrayList 就会有点复杂:

import java.util.ArrayList;
import java.util.List;

public class MergeSortedArray {
    public static void merge(int[] nums1, int m, int[] nums2, int n) {
        List<Integer> merged = new ArrayList<>();

        int p1 = 0;
        int p2 = 0;

        while (p1 < m && p2 < n) {
            if (nums1[p1] < nums2[p2]) {
                merged.add(nums1[p1]);
                p1++;
            } else {
                merged.add(nums2[p2]);
                p2++;
            }
        }

        while (p1 < m) {
            merged.add(nums1[p1]);
            p1++;
        }

        while (p2 < n) {
            merged.add(nums2[p2]);
            p2++;
        }

        // 将 merged 数组复制回 nums1
        for (int i = 0; i < merged.size(); i++) {
            nums1[i] = merged.get(i);
        }
    }

    public static void main(String[] args) {
        int[] nums1 = {1, 3, 5, 0, 0, 0};
        int[] nums2 = {2, 4, 6};
        int m = 3;
        int n = 3;

        merge(nums1, m, nums2, n);

        System.out.print("Merged Array: ");
        for (int num : nums1) {
            System.out.print(num + " ");
        }
    }
}

这种方法使用了额外的 ArrayList 来存储合并后的数组,然后将其复制回 nums1 数组。

注意,这种方法的空间复杂度为 O(m+n),不符合题目要求的原地修改输入数组的要求。

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

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

相关文章

Android系统原理性问题分析 - Android Java框架层的结构

声明 在Android系统中经常会遇到一些系统原理性的问题&#xff0c;在此专栏中集中来讨论下。Android系统&#xff0c;为了能够更好的理解Android的Java世界的运行规律&#xff0c;此篇分析Android Java框架的结构。此篇参考一些博客和书籍&#xff0c;代码基于Android 7.1.1&a…

资产处置求变,京东拍卖如何做好“价值枢纽”?

近年来&#xff0c;随着资产处置市场规模快速成长以及互联网行业飞速发展&#xff0c;金融资产、司法拍卖、罚没物资等处置方式从最初单纯线下拍卖逐渐落地互联网&#xff0c;服务专业化程度也在不断提高。为更好适应市场变化&#xff0c;满足不断增长的市场需求&#xff0c;5月…

NISP二级证书含金量如何

国家信息安全水平考试&#xff08;National Information Security Test Program&#xff0c;简称NISP&#xff09;&#xff0c;是由中国信息安全测评中心实施培养国家网络空间安全人才的项目。 为培养更多优秀的实践型网络安全人才&#xff0c;中国信息安全测评中心推出了国家…

替代MySQL半同步复制,Meta技术团队推出MySQL Raft共识引擎

作者&#xff1a;Anirban Rahut、Abhinav Sharma、Yichen Shen、Ahsanul Haque 原文链接&#xff1a;https://engineering.fb.com/2023/05/16/data-infrastructure/mysql-raft-meta/ 译者&#xff1a;ChatGPT 责编&#xff1a;张红月 MySQL Raft是MySQL数据库中一种基于Raft协议…

探索LeetCode【0010】正则表达式匹配(已懂,未练习)

目录 0.1 题目0.2 补充示例1. 参考B站视频2. 官方答案的评论-可用3. chatGPT的思路和解法-可用 0.1 题目 题目链接&#xff1a;【0010】正则表达式匹配 给你一个字符串 s 和一个字符规律 p&#xff0c;请你来实现一个支持 . 和 * 的正则表达式匹配。 . 匹配任意单个字符* 匹…

2023 RSAC|和衷共济 共同应对网络安全挑战

作为全球最具规模的安全大会&#xff0c;2023年RSA Conference的落幕也为安全行业的“何去何从”带来一定的启发性。 今年大会的主题是“Strong together”&#xff0c;主要来自于海伦凯勒的名言: “ Alone we can do so little; together we can do so much. ” 纵观2022年…

做完这个测试项目,我终于决定辞职·····

很迷茫&#xff0c;然后过得非常不如意&#xff0c;倒不是上一年的职业目标没达到&#xff0c;而是接下来的路根本不知道如何走。在没解决这个问题之前&#xff0c;或者说没搞清楚自己的方向之前&#xff0c;是迟迟不能落笔的&#xff0c;啊不&#xff0c;应该是落键盘。 下班…

JavaWeb-RequestResponse的使用

Request&Response 今日目标 掌握Request对象的概念与使用掌握Response对象的概念与使用能够完成用户登录注册案例的实现能够完成SqlSessionFactory工具类的抽取 1&#xff0c;Request和Response的概述 Request是请求对象&#xff0c;Response是响应对象。这两个对象在我们…

德尔玛IPO首日破发,市值蒸发超4亿

今日&#xff08;5月18日&#xff09;&#xff0c;小米“代工厂”广东德尔玛科技股份有限公司&#xff08;下称“德尔玛”&#xff0c;301332.SZ&#xff09;正式在深交所挂牌上市。 德尔玛此次IPO募资净额为12.31亿元&#xff0c;开盘价为14.81元/股&#xff0c;与发行价持平…

Call to undefined function bcadd()

先介绍一下当前使用的环境。同学们可以比较一下&#xff0c;看本篇文章是否可以提供帮助。 docker 部署 nginx 1.24php 8.1-fpm 再介绍一下框架&#xff0c;使用的是 "laravel 9.33.0" 其实这里跟 laravel 框架和 nginx 是没太多关系的&#xff0c;因为我们主要是使…

MySQL高级_第09章_性能分析工具的使用

MySQL高级_第09章_性能分析工具的使用 在数据库调优中&#xff0c;我们的目标就是 响应时间更快&#xff0c;吞吐量更大。利用宏观的监控工具和微观的日志分析可以帮我们快速找到调优的思路和方式。 1. 数据库服务器的优化步骤 当我们遇到数据库调优问题的时候&#xff0c;该…

Windows平台软件开发模型总结:V型模型、瀑布模型、迭代模型、增量模型、螺旋模型、原型模型

我是荔园微风&#xff0c;作为一名在IT界整整25年的老兵&#xff0c;今天总结一下Windows平台软件开发模型总结&#xff1a;V型模型、瀑布模型、迭代模型、增量模型、螺旋模型、原型模型。 很多人可能知道了&#xff0c;那就是在我们浙江省&#xff0c;从2021年年初到现在&…

内网 monorepo 配置指南(PNPM、YARN)

此处的内网是指没办法连接互联网进行依赖下载的环境&#xff0c;本文以windows平台为例 背景说明 绝大部分政府机关、国有企业都是在内网开发&#xff0c;无法从互联网同步依赖&#xff0c;就需要另辟蹊径解决项目依赖的问题。 传统的单包项目还好&#xff0c;从互联网机器将…

兼顾降本与增效,我们对存算分离的设计与思考

“降本增效”是最近企业常被提及的关键字&#xff0c;作为新时代企业发展的数据大脑&#xff0c;企业大数据团队需要持续探索如何在有限资源下创造更多价值。本文将以场景为"引"&#xff0c;技术为"核"&#xff0c;介绍如何基于 StarRocks 全新的存算分离架…

软考软件设计师真题与答案解析

1、2020下半年基础知识&#xff08;上午题&#xff09; 1、某计算机系统的CPU主频为2.8GHz。某应用程序包括3类指令&#xff0c;各类指令的CPI(执行每条指令所需要的时钟周期数)及指令比例如’下表所示。执行该应用程序时的平均CPI为&#xff08; &#xff09;&#xff1b;运算…

2023 操作系统 R 复习大纲( 适用于软件 21 级)

目录 01.操作系统的定义 02.操作系统的基本类型及特征 1.批处理操作系统&#xff08;单、多道&#xff09; 2.分时操作系统 3.实时操作系统 03.操作系统的功能及特征 04.进程的定义、特征 05.进程基本状态及其转换原因 06.进程互斥、同步 07.进程控制块的内容、作用 …

Android Studio开发之路 (一)开发环境搭建以及问题记录

一、安装 Android Studio 安装配置教程 这个文章讲的很全面&#xff08;包括了jdk的配置&#xff09;&#xff0c;我安装了1.8.0版本的JDK 以及 2022.2.1版本的Android Studio ,安装目录都是自定义的&#xff0c;安装完成之后的目录如下&#xff08;项目目录也放到这里了&…

医院上线“报告中心”,实现报告查询“四个更好”

为进一步提升患者的就诊体验&#xff0c;不少医院部署云影像后&#xff0c;再次上线博为软件报告中心信息系统&#xff0c;患者和家属动动手指就能在自己手机上随时随地看到检查检验报告&#xff0c;彻底告别传统的纸质报告单方式&#xff0c;实现检查检验数据永久保存。 博为…

【Java多线程编程】wait与notify方法详解

前言 我们知道&#xff0c;线程的调度是无序的&#xff0c;但有些情况要求线程的执行是有序的。因此&#xff0c;我们可以使用 wait() 方法来使线程执行有序。 本期讲解 Java 多线程中 synchronized 锁配套使用的 wait 方法、notify方法和notifyAll方法&#xff0c;以及 wait 方…

jQuery 操作 DOM 及 CSS

jQuery 操作 DOM 及 CSS 1. jQuery 修改|获取页面元素文本及属性值 text() - 设置或返回所选元素的文本内容 html() - 设置或返回所选元素的内容&#xff08;包括 HTML 标签&#xff09; val() - 设置或返回表单字段的值 attr() - 方法用于获取属性值。 1.1 举例&#xff…