Java LeetCode篇-深入了解关于数组的经典解法

news2024/11/27 0:46:39

🔥博客主页: 【小扳_-CSDN博客】
❤感谢大家点赞👍收藏⭐评论✍
 

 

 

文章目录

        1.0 轮转数组

        1.1 使用移位的方式

        1.2 使用三次数组逆转法

        2.0 消失的数字

        2.1 使用相减法

        2.2 使用异或的方式

        3.0 合并两个有序数组

        3.1 使用三指针方式

        3.2 使用合并排序方式

        4.0 删除有序数组中的重复项

        4.1 使用双指针方式

        5.0 移除元素

        5.1 使用双指针方式

        6.0 杨辉三角

        6.1 使用二维数组的方式


 

        1.0 轮转数组

题目:

        给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。

示例 1:

输入: nums = [1,2,3,4,5,6,7], k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右轮转 1 步: [7,1,2,3,4,5,6]
向右轮转 2 步: [6,7,1,2,3,4,5]
向右轮转 3 步: [5,6,7,1,2,3,4]

        1.1 使用移位的方式

        先创建一个新的数组来记录需要进行右轮转的元素,然后将数组前面剩余的元素进行遍历 "移" 到后面,即覆盖。如例题1:先将 [5,6,7] 这 k 个元素使用新的数组来暂时存放,接着将 [1,2,3,4] 从后往前遍历,即将 4 移到原来 7 的位置,3 移到 原来 6 的位置,2 移到原来 5 的位置......即  nums[nums.length - i ]  = nums[ nums.length - k - i ]  i  从 1 开始直到 i == nums.length - k 时,则结束循环。最后,将需要轮转的元素进行数组 temp[] 下标一个个对应赋值到 nums[] 数组中即可。

代码如下:

    public static void rotate(int[] nums,int k) {
        if(nums.length == 1 || nums.length == 0) {
            return;
        }
        k %= nums.length;
        int[] temp = new int[k];
        System.arraycopy(nums,nums.length - k, temp, 0,k);
        System.arraycopy(nums,0,nums,k,nums.length - k);
        for(int i = 0;i < temp.length ; i++) {
            nums[i] = temp[i];
        }
    }

       这里使用了相关的 API ,总体上来说思路是一样的。一般来说,这种算法时间复杂度会较高。        

        1.2 使用三次数组逆转法

        使用三次逆转法,让数组旋转k次     

                        1. 整体逆置

                        2. 逆转子数组[0, k - 1]

                        3. 逆转子数组[k, size - 1]

代码如下:

    public static void fun(int[] arr, int k) {
        k %= arr.length;
        rotate(arr,0,arr.length - 1);
        rotate(arr,0,k-1);
        rotate(arr,k, arr.length-1);
    }
    public static void rotate(int[] arr,int left, int right) {
        while (left < right) {
            int temp = arr[left];
            arr[left] = arr[right];
            arr[right] = temp;
            left++;
            right--;
        }
    }

流程图如下:

        

        2.0 消失的数字

题目:

        数组 nums 包含从 到 的所有整数,但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在 O(n) 时间内完成吗?

示例 1:

输入:[3,0,1]
输出:2

示例 2:

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

       2.1 使用相减法

        定义 int sum ,然后遍历 0 到 n 的所有整数都加起来,接着再跟将 nums 的所以数字加起来进行比较两者相减即可得出 nums 数组中 "消失的数字" 。如例题:numsSum = 3 + 0 + 1 , nSum = 0 + 1 + 2 + 3,再接着 nSum - numsSum == 2 ,两者相减即可得到消失的数字为: 2 。

代码如下:

    public static int disappearing1(int[] arr) {
        int sum1 = 0;
        int sum2 = 0;
        for (int i = 0; i < arr.length; i++) {
            sum1 += i;
            sum2 += arr[i];
        }
        return (sum1 += arr.length) - sum2;
    }

        缺陷:如果数组中元素比较多,相加完成之后容易溢出。

       2.2 使用异或的方式

        采用异或的方式解决,因为两个相同的数字异或的结果是 0,因此:将 0~N 之间的数字,与数组中的每个数字异或,最终的结果就是丢失的数字。

代码如下:

    public static int disappearing(int[] arr) {

        int data = 0;
        for (int i = 0; i < arr.length; i++) {
            data ^= arr[i];
            data ^= i;
        }
        data ^= arr.length;
        return data;
    }

        分析:可以将将其理解为 “消消乐” ,即若两个数相同就抵消为 0 ,那么现在目前有两个袋子,一个袋子装满了 0 到 n 张卡片,其中每一种只有一片,也就是说,该袋子里面就有 n + 1 张卡片,在另一个袋子里面装有 0 到 n 张中缺少了一张卡片,即该袋子中有 n 张卡片,接着进行每一次将分别从两个袋子拿出不同的卡片进行对比,如果相同的话则抵消掉了,不相同的话,得保存起来。就这样一直对比下去,最终会发现留下来的就是另一个袋子所缺少的卡片了。

        3.0 合并两个有序数组

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

请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。

示例 1:

输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
解释:需要合并 [1,2,3] 和 [2,5,6] 。
合并结果是 [1,2,2,3,5,6] ,其中斜体加粗标注的为 nums1 中的元素。

        3.1 使用三指针方式

        定义三个指针分别为:i 指向 nums1 中的最后一个有效元素j 指向 nums2 中最后一个有效元素k 指向 nums1 中最后一个索引位置。接着 nums[i] 与 nums[j] 进行比较大小,得出较大的元素就放到 nums[k] 中,以此类推,直到 i < 0 或者 j < 0 时,则循环停止。最后来判断,若 i > 0 ,本来剩余的元素就在 nums1 中,则不用再继续下去了,任务结束了;若 j > 0 ,需要将 nums2 中的元素进行遍历拷贝到 nums1 中

代码如下:

public void merge(int[] nums1, int m, int[] nums2, int n) {
        int k = nums1.length - 1;
        int i = m - 1;
        int j = n - 1;
        while(i >= 0 && j >= 0) {
            if(nums1[i] > nums2[j]) {
                nums1[k] = nums1[i];
                k--;
                i--;
            }else if(nums1[i] <= nums2[j]) {
                nums1[k] = nums2[j];
                k--;
                j--;
            }
        }

        if(j >= 0) {
            System.arraycopy(nums2,0,nums1,0,j+1);

        }

    }

        3.2 使用合并排序方式

        这个思路很简单,可以直接将 nums2 中的元素拷贝到 nums1 中,然后直接排序即可。这里就不过多赘述了。

        4.0 删除有序数组中的重复项

题目:

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

示例 1:

输入:nums = [1,1,2]
输出:2, nums = [1,2,_]
解释:函数应该返回新的长度 2,并且原数组 nums 的前两个元素被修改为 1, 2不需要考虑数组中超出新长度后面的元素。

示例 2:

输入: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。不需要考虑数组中超出新长度后面的元素。

        4.1 使用双指针方式

        先定义两个指针分别指向,一个指针: i = 0 ,一开始时指向数组中第一个元素另一个指针:j = 1。分两种情况来解决,第一种情况是,当 nums[i] == nums[j] 时,继续让 j 走下去,直到 j == nums.length 时,则结束循环;第二种情况是,当 nums[i] != nums[j] 时,让 nums[i + 1] = nums[j] ,i++,j++ ,同样直到 j == nums.length 时,则结束循环。最后返回 i+1 即可。

代码如下:

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

        5.0 移除元素

题目:

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

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

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

示例 1:

输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。

示例 2:

输入:nums = [0,1,2,2,3,0,4,2], val = 2
输出:5, nums = [0,1,3,0,4]
解释:函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。注意这五个元素可为任意顺序。你不需要考虑数组中超出新长度后面的元素。

        5.1 使用双指针方式

        先定义两个指针,对于 left 这个指针来说,一开始指向数组下标为 0 对于 right 这个指针来说,一开始指向数组下标也为 0 处,然后 rigth 一直 right++ 自加,在这个过程中,需要先判断,若 nums[right]  != val 时,则需要将这个值拷贝到 nums[left] 中 ,left++right++ ;若 nums[right] == val 时,right++ 即可,直到 right == nums.length 时,则结束循环。

代码如下:

    public int removeElement(int[] nums, int val) {
        int n = nums.length;
        int left = 0;
        for (int i = 0; i < n; i++) {
            if (nums[i] != val) {
                nums[left] = nums[i];
                left++;
            }
        }
        return left;
    
    }

       

        6.0 杨辉三角

题目:

        给定一个非负整数 numRows生成「杨辉三角」的前 numRows 行。

在「杨辉三角」中,每个数是它左上方和右上方的数的和。

        

示例 1:

输入: numRows = 5
输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]

示例 2:

输入: numRows = 1
输出: [[1]]

        6.1 使用二维数组的方式

        可以把这个问题看成是一个二维数组,外层循环为 k 行数(层数),内层为 l 列数。当 l == 0 或者 k == l 时,该二维数组中存放的是 1 ;其他情况则为当前的数值为:上一层行数同一列的 data1 + 上一层行数少一列的 data2 。

 代码如下:

    public List<List<Integer>> generate(int numRows) {
      
        
        List<List<Integer>> i = new ArrayList<>();
        for (int k = 0; k < numRows; k++) {
            List<Integer> j = new ArrayList<>();
            for (int l = 0; l <= k ; l++) {
                if ( l == 0 || k == l) {
                    j.add(1);
                } else {
                    j.add(i.get(k-1).get(l) + i.get(k-1).get(l-1));
                }
            }
            i.add(j);
        }
         return i;


    }

        需要注意的是,实现集合来实现,而不是数组。

需要了解相关集合的内容可以点击该链接:进阶JAVA篇-深入了解 List 系列集合-CSDN博客

 

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

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

相关文章

欧飞信发布WIFI7网卡模组—O7851PM

在当今飞速发展的科技世界中&#xff0c;流畅快速的网络连接已经成为我们生活中不可或缺的一部分。为了满足现代应用环境对于高速、稳定无线连接的需求&#xff0c;欧飞信于今日推出一款最新的WIFI7网卡模组——O7851PM&#xff0c;标志着我们欧飞信在无线通信领域的巅峰技术成…

docker 安装oracle 11,配置客户端远程连接

最近由于工作需要&#xff0c;oracle11数据库的导入导出&#xff0c;所以自己在电脑上模拟个数据库环境&#xff0c; 1.docker的安装&#xff0c;可以参考之前文档&#xff0c;也可以直接yum install 包名字安装 2.下载镜像 docker pull registry.cn-hangzhou.aliyuncs…

数据结构 | TOP-K问题

数据结构 | TOP-K问题 文章目录 数据结构 | TOP-K问题随机生成一些数据&#xff0c;找前k个最大值进行取前k个值建堆找到了前k个结果以及全部代码 TOP-K问题&#xff1a;即求数据结合中前K个最大的元素或者最小的元素&#xff0c;一般情况下数据量都比较大。 就是从N个数里面找…

【香橙派】实战记录2——烧录安卓镜像及基本功能

文章目录 一、安卓烧录二、安卓基本功能1、蓝牙2、相机功能3、投屏 一、安卓烧录 检查环境&#xff1a;检查PC系统&#xff0c;确保有Microsoft Visual C 2008 Redistrbutable - x86&#xff0c;否则在官网下载的官方工具 - 安卓镜像烧录工具里运行vcredist_x86.exe。 插入存储…

bash编程 数组和for循环的应用

bash编程 数组和for循环的应用 1、问题背景2、bash 定义数组3、for循环遍历输出数组所有元素4、编写bash脚本输出每个端口是否在监听状态 1、问题背景 linux服务器开机后&#xff0c;需要检查一组端口是否在监听&#xff0c;以便判断这些端口对应的服务是否在运行。可以考虑使…

Android Termux SFTP如何实现远程文件传输

文章目录 1. 安装openSSH2. 安装cpolar3. 远程SFTP连接配置4. 远程SFTP访问4. 配置固定远程连接地址 SFTP&#xff08;SSH File Transfer Protocol&#xff09;是一种基于SSH&#xff08;Secure Shell&#xff09;安全协议的文件传输协议。与FTP协议相比&#xff0c;SFTP使用了…

矩阵置零[中等]

优质博文&#xff1a;IT-BLOG-CN 一、题目 给定一个m x n的矩阵&#xff0c;如果一个元素为0&#xff0c;则将其所在行和列的所有元素都设为0。请使用原地算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&#xff1a;[[1,0,1],[0,0,0],[…

科技云报道:再现降价潮背后:云厂商们的“焦虑”

科技云报道原创。 云服务市场再现降价潮。 从上个月开始&#xff0c;各大云厂商开启了新一轮降价&#xff0c;尤其是到双十一期间降价幅度达到了顶峰。比如说&#xff0c;阿里云的“金秋创云季”&#xff0c;华为云的多样化优惠&#xff0c;腾讯云对轻量云服务器的聚焦。 回…

手摸手Element-ui路由VueRoute

后端WebAPI准备 https://router.vuejs.org/zh/guide/ https://v3.router.vuejs.org/zh/installation.html <template><el-table:data"tableData"style"width: 100%":row-class-name"tableRowClassName"><!-- <el-table-colum…

线性分类器--数据处理

数据集划分 通常按照 70%&#xff0c;20% &#xff0c;10% 来分数据集 数据处理 斯坦福的线性分类器体验 http://vision.stanford.edu/teaching/cs231n-demos/linear-classify/

2020年12月 Scratch(四级)真题解析#中国电子学会#全国青少年软件编程等级考试

Scratch等级考试(1~4级)全部真题・点这里 一、单选题(共15题,每题2分,共30分) 第1题 陶朱家开了一间小卖部,学了编程的他想编写一个程序帮助分析小卖部各种商品的售卖情况。如下图所示,目前各个商品的名称和销售量分别存在了两张列表里,一一对应,并且每一样商品的销…

springboot实现验证码功能

转载自 : www.javaman.cn 1、编写工具类生成4位随机数 该工具类主要生成从0-9&#xff0c;a-z&#xff0c;A-Z范围内产生的4位随机数 /*** 产生4位随机字符串*/public static String getCheckCode() {String base "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn…

JAVA:深入探讨String性能优化让你的程序更高效

1、简述 在现代软件开发中&#xff0c;字符串&#xff08;String&#xff09;是一个不可或缺的数据类型&#xff0c;几乎每个应用程序都在某种程度上使用字符串。然而&#xff0c;由于字符串操作的频繁性质&#xff0c;它们可能成为程序性能的瓶颈之一。在本文中&#xff0c;我…

csgo/steam搬砖项目新手教程

饰品市场持续下跌&#xff0c;CSGO搬砖还有搞头吗&#xff1f; 蒸砖搬砖工程特别适合工作比较忙&#xff0c;没有太多时间操作的人。在不耽误主业的前提下&#xff0c;增加收入来源&#xff0c;不失为一个好办法。在做这个项目的时候&#xff0c;最主要的是选择有利可图的道具进…

电脑热点无法使用,分配IP地址失败

电脑热点无法使用&#xff0c;分配IP地址失败 不知道从什么时候起电脑开热点就无法连接上了&#xff0c;手机提示无法分配IP地址&#xff0c;电脑正常显示。 设置共享网络连接时提示以下内容。 无法启用internet连接共享,为LAN连接配置的IP地址需要使用自动IP寻址 查阅相关资…

RISC-V_WCH系列微控器软件体系云端快速架构

1 概述 RISC-V内核的微控器MCU&#xff0c;正在以更高的性价比&#xff0c;快速取代传统的各类ARM系列微控制处理器。 针对常用的芯成RISC-V内核的泌恒WCH系列微控器MCU&#xff0c;推出了&#xff1a;RISC-V_WCH系列微控器软件体系快速架构云平台。只要以身份证号码做用户名…

C语言——打印出所有的“水仙花数”

所谓水仙花数,是指一个3位数,其各位数字立方和等于该数本身。水仙花数是指一个三位数&#xff0c;它的每个位上的数字的立方和等于它本身。例如&#xff0c;153是一个水仙花数&#xff0c;因为1^3 5^3 3^3 153。 #define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>…

R语言实操记录——R包无法安装,报错:Warning in system(cmd) : ‘make‘ not found

R语言 R语言实操记录——R包无法安装&#xff0c;报错&#xff1a;Warning in system(cmd) : ‘make‘ not found 文章目录 R语言一、起因二、具体步骤2.1、确认问题源2.2、安装RTools2.3、与R(/Rstudio)绑定2.4、验证可行性 三、疑惑 一、起因 R语言在包的安装上是真的方便&…

概率论与数理统计-第4章 随机变量的数字特征

第4章 随机变量的数字特征 4.1数学期望 一、离散型随机变量的数学期望 定义1设离散型随机变量X的概率分布为 P{Xxi}pi,i1,2,…,如果级数绝对收敛&#xff0c;则定义X的数学期望&#xff08;又称均值&#xff09;为 二、连续型随机变量的数学期望 定义2设X是连续型随机变量…

【前端开发】Remix与Next.js

很容易&#xff0c;我们被问到的最大问题是&#xff1a; Remix与Next.js有何不同&#xff1f; 看来我们必须回答这个问题&#xff01;我们想直接而不带戏剧性地解决这个问题。如果你是Remix的粉丝&#xff0c;并且想开始在推特上对这篇文章做出沾沾自喜的反应&#xff0c;我们恳…