数组方法汇总

  • 数组和链表类似,都是用双指针,但数组不需要额外的指针,可以使用索引来当作指针。(链表的时候要注意,什么时候是移动的指针,什么时候是改变的节点)
  • 删除有序数组中的重复项
    注意,本题中的数组是有序的,但是有重复项,我们要进行去重,这和链表类似,用快慢指针,快指针不等于慢指针的时候,我们用快指针将慢指针覆盖,然后移动指针。相同的时候移动快指针就好。
    代码中有个需要注意的地方,我们在while循环中,当快慢指针不同的时候,我们需要先移动慢指针,然后再替换,因为这样才能避免慢指针这个地方的元素被覆盖,我们是要去除慢指针后面那个重复元素。
    我们要返回的是数组中不重复元素的个数,所以应该索引+1.

在这里插入图片描述

int removeDuplicates(int[] nums) {if (nums.length == 0) {return 0;}int slow = 0, fast = 0;while (fast < nums.length) {if (nums[fast] != nums[slow]) {slow++;// 维护 nums[0..slow] 无重复nums[slow] = nums[fast];}fast++;}// 数组长度为索引 + 1return slow + 1;
}

下面是链表的代码(slow.next=fast,就是改变的链表节点连接,而slow = slow.next则是移动的指针,走向下一个节点进行判断)
在这里插入图片描述

ListNode deleteDuplicates(ListNode head) {if (head == null) return null;ListNode slow = head, fast = head;while (fast != null) {if (fast.val != slow.val) {// nums[slow] = nums[fast];slow.next = fast;// slow++;slow = slow.next;}// fast++fast = fast.next;}// 断开与后面重复元素的连接slow.next = null;return head;
}
  • 移除元素
    这个是给定了一个值,让我们移除数组中和这个值相同的元素,其实做法也是快慢指针,和上面题类似,但这里有个细节,我们在判断当这个值和快指针不相等的时候,我们要先替换慢指针的地方,然后再移动慢指针,因为我们是要删除掉与x相等的元素,只要有就删,一个不能留。快指针是用来遍历元素,找到与x不同的值,然后保留在慢指针的位置,慢指针是存储位置的索引。
int removeElement(int[] nums, int val) {int fast = 0, slow = 0;while (fast < nums.length) {if (nums[fast] != val) {nums[slow] = nums[fast];slow++;}fast++;}return slow;
}
  • 移动0
    题中要求将数组的值为0的元素都移动到数组末尾。我们可以先移除数组中的0,然后在数组后面进行补0即可。
    所以我们可以借助上题的删除指定元素的代码,然后删除0,然后再用0补齐数组即可
void moveZeroes(int[] nums) {// 去除 nums 中的所有 0,返回不含 0 的数组长度int p = removeElement(nums, 0);// 将 nums[p..] 的元素赋值为 0for (; p < nums.length; p++) {nums[p] = 0;}
}int removeElement(int[] nums, int val) {int fast = 0, slow = 0;while (fast < nums.length) {if (nums[fast] != val) {nums[slow] = nums[fast];slow++;}fast++;}return slow;
}
  • 二分查找
    二分查找我们可以选择左闭右开或者左闭右闭的区间。选择左闭右开,那么左和右肯定不会相等,while(left<right),然后left=mid+1,right=mid
class Solution {public int search(int[] nums, int target) {int left = 0, right = nums.length;while (left < right) {int mid = left + ((right - left) >> 1);if (nums[mid] == target)return mid;else if (nums[mid] < target)left = mid + 1;else if (nums[mid] > target)right = mid;}return -1;}
}
  • 两数之和Ⅱ
    给你一个下标从 1 开始的整数数组 numbers ,该数组已按 非递减顺序排列 ,请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1] 和 numbers[index2] ,则 1 <= index1 < index2 <= numbers.length
    数组有序,我们用双指针,为了满足题中索引要求,我们可以使用相向双指针,即left=0,right=nums.length-1。然后来进行判断。注意,两个索引是不相等的,所以我们的while循环中,应该是left<right
int[] twoSum(int[] nums, int target) {// 一左一右两个指针相向而行int left = 0, right = nums.length - 1;while (left < right) {int sum = nums[left] + nums[right];if (sum == target) {// 题目要求的索引是从 1 开始的return new int[]{left + 1, right + 1};} else if (sum < target) {left++; // 让 sum 大一点} else if (sum > target) {right--; // 让 sum 小一点}}return new int[]{-1, -1};
}
  • 翻转数组
void reverseString(char[] s) {// 一左一右两个指针相向而行int left = 0, right = s.length - 1;while (left < right) {// 交换 s[left] 和 s[right]char temp = s[left];s[left] = s[right];s[right] = temp;left++;right--;}
}
  • 回文串判断
    回文串就是正着读和反着读都一样的字符串
    判断字符串是不是回文串
boolean isPalindrome(String s) {// 一左一右两个指针相向而行int left = 0, right = s.length() - 1;while (left < right) {if (s.charAt(left) != s.charAt(right)) {return false;}left++;right--;}return true;
}
  • 最长回文子串
    我们可以用双指针来做,但我们要找最长的回文子串,是连续的,我们可以从中心向两端扩散的双指针。
    因为我们是从中心往两边走,找最长的回文子串,如果整个子串都是回文的,那我们走到最左边0的位置,和最右边nums.length-1的位置也符合,这个时候我们的指针还会移动,此时L已经走到了-1,而R已经走到了nums.length,所以我们在截取字符串的时候是截取的substring(l+1,r)。
String longestPalindrome(String s) {String res = "";for (int i = 0; i < s.length(); i++) {// 以 s[i] 为中心的最长回文子串String s1 = palindrome(s, i, i);// 以 s[i] 和 s[i+1] 为中心的最长回文子串String s2 = palindrome(s, i, i + 1);// res = longest(res, s1, s2)res = res.length() > s1.length() ? res : s1;res = res.length() > s2.length() ? res : s2;}return res;
}
// 在 s 中寻找以 s[l] 和 s[r] 为中心的最长回文串
String palindrome(String s, int l, int r) {// 防止索引越界while (l >= 0 && r < s.length()&& s.charAt(l) == s.charAt(r)) {// 双指针,向两边展开l--; r++;}// 返回以 s[l] 和 s[r] 为中心的最长回文串return s.substring(l + 1, r);
}
  • 合并两个有序数组
    我们不能用新数组,但是如果从前向后遍历的话,会覆盖掉nums1中的元素,我们可以将双指针初始化在数组的尾部,然后从后向前进行合并。
class Solution {public void merge(int[] nums1, int m, int[] nums2, int n) {// 两个指针分别初始化在两个数组的最后一个元素(类似拉链两端的锯齿)int i = m - 1, j = n - 1;// 生成排序的结果(类似拉链的拉锁)int p = nums1.length - 1;// 从后向前生成结果数组,类似合并两个有序链表的逻辑while (i >= 0 && j >= 0) {if (nums1[i] > nums2[j]) {nums1[p] = nums1[i];i--;} else {nums1[p] = nums2[j];j--;}p--;}// 可能其中一个数组的指针走到尽头了,而另一个还没走完// 因为我们本身就是在往 nums1 中放元素,所以只需考虑 nums2 是否剩元素即可while (j >= 0) {nums1[p] = nums2[j];j--;p--;}}
}
  • 有序数组的平方
    本题其实也是合并数组,只不过把远数字换成平方,我们仍采用双指针,因为这个数组元素的平方的最值,肯定是在数组的两端。我们采用相向双指针,注意,新数组应该从后往前添加,因为我们是从两端开始算的最大值
class Solution {public int[] sortedSquares(int[] nums) {int n = nums.length;// 两个指针分别初始化在正负子数组绝对值最大的元素索引int i = 0, j = n - 1;// 得到的有序结果是降序的int p = n - 1;int[] res = new int[n];// 执行双指针合并有序数组的逻辑while (i <= j) {if (Math.abs(nums[i]) > Math.abs(nums[j])) {res[p] = nums[i] * nums[i];i++;} else {res[p] = nums[j] * nums[j];j--;}p--;}return res;}
}
  • 有序序列转数组
    一个有序数组,给定abc,对每一个元素计算f(x) = ax2 + bx + c,按照升序返回数组
    所以这道题的关键也是在 nums 的开头和结尾设置 i, j 双指针相向而行,执行合并有序数组的逻辑
class Solution {public int[] sortTransformedArray(int[] nums, int a, int b, int c) {// 双指针,相向而行,逼近对称轴int i = 0, j = nums.length - 1;// 如果开口朝上,越靠近对称轴函数值越小// 如果开口朝下,越靠近对称轴函数值越大int p = a > 0 ? nums.length - 1 : 0;int[] res = new int[nums.length];// 执行合并两个有序数组的逻辑while (i <= j) {int v1 = f(nums[i], a, b, c);int v2 = f(nums[j], a, b, c);if (a > 0) {// 如果开口朝上,越靠近对称轴函数值越小if (v1 > v2) {res[p--] = v1;i++;} else {res[p--] = v2;j--;}} else {// 如果开口朝下,越靠近对称轴函数值越大if (v1 > v2) {res[p++] = v2;j--;} else {res[p++] = v1;i++;}}}return res;}int f(int x, int a, int b, int c) {return a*x*x + b*x + c;}
}
  • 区域和检索
    用一维前缀和,前缀和数组比之前数组多一位,并且在presum[0]=0,然后再进行计算,公式为presum[i]=presum[i-1]+nums[i-1],计算两个索引left和right之间的元素和直接可以用presum[right+1]-presum[left]。因为presum[right+1]是计算到了nums中索引从0到right的位置,而presum[left]是计算到了nums中索引从0到left-1的位置,所以二者相减就是left到right之间的元素和。
    在这里插入图片描述
class NumArray {// 前缀和数组private int[] preSum;/* 输入一个数组,构造前缀和 */public NumArray(int[] nums) {// preSum[0] = 0,便于计算累加和preSum = new int[nums.length + 1];// 计算 nums 的累加和for (int i = 1; i < preSum.length; i++) {preSum[i] = preSum[i - 1] + nums[i - 1];}}/* 查询闭区间 [left, right] 的累加和 */public int sumRange(int left, int right) {return preSum[right + 1] - preSum[left];}
}
  • 二维前缀和 在这里插入图片描述
    同理,二维前缀和数组我们也多建一行一列,索引从1开始遍历,然后,preSum[i][j] = preSum[i-1][j] + preSum[i][j-1] + matrix[i - 1][j - 1] - preSum[i-1][j-1];
    // 计算子矩阵 [x1, y1, x2, y2] 的元素和
    preSum[x2+1][y2+1] - preSum[x1][y2+1] - preSum[x2+1][y1] + preSum[x1][y1];
class NumMatrix {// 定义:preSum[i][j] 记录 matrix 中子矩阵 [0, 0, i-1, j-1] 的元素和private int[][] preSum;public NumMatrix(int[][] matrix) {int m = matrix.length, n = matrix[0].length;if (m == 0 || n == 0) return;// 构造前缀和矩阵preSum = new int[m + 1][n + 1];for (int i = 1; i <= m; i++) {for (int j = 1; j <= n; j++) {// 计算每个矩阵 [0, 0, i, j] 的元素和preSum[i][j] = preSum[i-1][j] + preSum[i][j-1] + matrix[i - 1][j - 1] - preSum[i-1][j-1];}}}// 计算子矩阵 [x1, y1, x2, y2] 的元素和public int sumRegion(int x1, int y1, int x2, int y2) {// 目标矩阵之和由四个相邻矩阵运算获得return preSum[x2+1][y2+1] - preSum[x1][y2+1] - preSum[x2+1][y1] + preSum[x1][y1];}
}

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

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

相关文章

C语言经典例题(18) --- 判断字母、三角形判断、衡量人体胖瘦程度、翻转金字塔图案、平均身高

1.判断是不是字母 题目描述: KK想判断输入的字符是不是字母&#xff0c;请帮他编程实现。 输入描述: 多组输入&#xff0c;每一行输入一个字符。 输出描述: 针对每组输入&#xff0c;输出单独占一行&#xff0c;判断输入字符是否为字母&#xff0c;输出内容详见输出样例。 输…

36.基于CAS实现的java类

JUC, java.util.concurrent并发工具包下。 1.原子整数 AtomicInteger AtomicLong AtomicBoolean 底层用的CAS来实现。 AtomicInteger类的incrementAndGet方法&#xff0c;addAndGet方法 public static void main(String[] args) {AtomicInteger atomicInteger new Atom…

突破编程_C++_网络编程(TCPIP 四层模型(网络层(1))

1 网络层概述 TCP/IP 四层模型中的网络层是模型中的核心组成部分&#xff0c;它主要负责处理数据包的路由和转发&#xff0c;确保数据能够在源主机和目标主机之间准确地传输。 一、主要功能 网络层的主要功能是实现数据包的选路和转发。当数据从应用层传输到传输层后&#x…

Coursera自然语言处理专项课程04:Natural Language Processing with Attention Models笔记 Week01

Natural Language Processing with Attention Models Course Certificate 本文是学习这门课 Natural Language Processing with Attention Models的学习笔记&#xff0c;如有侵权&#xff0c;请联系删除。 文章目录 Natural Language Processing with Attention ModelsWeek 01…

c# wpf style 简单试验

1.概要 wpf style 用来控制控件的样式 2.代码 <Window x:Class"WpfApp2.Window5"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.…

MCAL SPI配置

用的是Qspi0 SpiDriver 要配置 4个选项 Spichannel SpiExternalDevice SpiJob SpiSequence Mcu 模块配置 dma配置

数组分割

题目 问题描述 小蓝有一个长度为 N 的数组 A [A0, A1, . . .&#xff0c;AN−1]。现在小蓝想要从 A 对应的数组下标所构成的集合 I {0, 1, 2, . . . , N − 1} 中找出一个子集 R1&#xff0c;那么 R1在 I 中的补集为 R2。记 S1 ∑ r ∈ R1 Ar&#xff0c;S2 ∑ r ∈ R2 Ar…

职场迷航?MBTI测试为你指明方向,找到最匹配的职业!

MBTI简介 MBTI的全名是Myers-Briggs Type Indicator。它是一种迫选型、自我报告式的性格评估工具&#xff0c;用以衡量和描述人们在获取信息、作出决策、对待生活等方面的心理活动规律和性格类型。 类型指标 美国的凯恩琳布里格斯和她的女儿伊莎贝尔布里格斯迈尔斯研制了迈尔…

归类一些vim的插件,需要时来看

本文结构&#xff1a; a、简介 b、一些插件名称及简要介绍 a、之前我一篇文章说了在vim中安装了一个可以自动补全")",">"等符号的插件autopairs,里面也有详细的安装及配置步骤。基于有些小伙伴想要了解些别的vim插件和自己有时候可能会有些灵感想要写…

开发环境->生产环境

1、数据迁移 不涉及docker # 以数据库用户导出数据 mysqldump -h 192.168.1.168 -P 3307 -u abragent -pabragebb17 abragent > abragent.sql# 以root用户导出数据 mysqldump -h 192.168.1.168 -P 3307 -u root -p8d3Ba1b abragent > abragent.sql 涉及docker …

递归算法练习

递归算法是所有算法中较难的一种&#xff0c;依靠他代码的简洁和清晰地逻辑很受人们喜欢&#xff0c;但是新手入门递归还是会被他不同寻常的思路吓到&#xff0c;其实面对递归问题我们只需要看清题目&#xff0c;分析出要求&#xff0c;有清晰的解题思路&#xff0c;只要仔细分…

十九、Rust Tcp Rpc 示例

前一篇&#xff0c;我们演示了 rust grpc 的应用&#xff0c;但 grpc 是基于 http 的&#xff0c;按理说其协议更重&#xff0c;同时也确见到网友验证过&#xff0c;相比 http 的 rpc&#xff0c;tpc 下的 rpc 性能确实更有优势。 同时&#xff0c;不同于 grpc 要编写一份 “中…

系统分析师-综合知识-应用数学与经济管理

系统分析师-综合知识-应用数学与经济管理 更多软考资料 https://ruankao.blog.csdn.net/ 文章目录 系统分析师-综合知识-应用数学与经济管理概述最小生成树真题-给出图真题-给出表 最短路径关键路径关键路径基本关键路径升级 网络与最大流量指派问题最小解最大解 线性规划决策…

软考--软件设计师(软件工程总结2)

目录 1.测试方法 2.软件项目管理 3.软件容错技术 4.软件复杂性度量 5.结构化分析方法&#xff08;一种面向数据流的开发方法&#xff09; 6.数据流图 1.测试方法 软件测试&#xff1a;静态测试&#xff08;被测程序采用人工检测&#xff0c;计算机辅助静态分析的手段&…

虚拟机打不开

问题 另一个程序已锁定文件的一部分&#xff0c;进程无法访问 打不开磁盘“G:\centeros\hadoop104kl\hadoop100-cl2.vmdk”或它所依赖的某个快照磁盘。 模块“Disk”启动失败。 未能启动虚拟机。 原因 前一次非正常关闭虚拟机导致.lck 文件是VMWare软件的一种磁盘锁文件&…

蓝桥杯算法题:外卖店优先级

“饱了么”外卖系统中维护着 N 家外卖店&#xff0c;编号 1∼N。每家外卖店都有一个优先级&#xff0c;初始时 (0时刻) 优先级都为 0。每经过 1个时间单位&#xff0c;如果外卖店没有订单&#xff0c;则优先级会减少 1&#xff0c;最低减到 0&#xff1b;而如果外卖店有订单&am…

特定领域软件体系结构

1.DSSA的定义 简单地说&#xff0c;DSSA&#xff08;Domain Specific Software Architecture&#xff09;就是在一个特定应用领域中为一组应用提供组织结构参考的标准软件体系结构。 从功能覆盖的范围的角度有两种理解DSSA中领域的含义的方式&#xff1a; &#xff08;1&#x…

使用Python写简单的点云高斯滤波

一、代码 Python import numpy as np import open3d as o3ddef apply_gaussian_filter(pcd, k=30, sigma=1.0):"""对点云应用高斯滤波。参数:pcd (open3d.geometry.PointCloud): 输入的点云。k (int): 每个点的邻居数量。sigma (float): 高斯核的标准差。返回…

极海APM32电机驱动板记录(二)

文章目录 1、解除写保护2、极海驱动板资源概述3、新建工程4、点灯5、嘀嗒定时器6、中断7、串口打印8、adc读取9、i2c尝试10、定时器测试11、电机驱动pwm测试 上一篇文章算是简单了解了一下极海的板子开发环境吧&#xff0c;结果前几天板子来了&#xff0c;然后发现一个大bug&am…

12、高精度加法(含源码)

高精度加法 难度&#xff1a;简单 题目描述 给定两个正整数&#xff0c;计算它们的和 输入格式 共两行&#xff0c;每行包含一个整数。 输出格式 共一行&#xff0c;包含所求的和。 数据范围&#xff1a; 1≤整数长度≤100000输入样例&#xff1a; 12 23输出样例&…