十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
由于数组是有序的,因此只要判断当前数组元素是否与下一个数组元素相等即可,如果相等,那么就继续向后遍历,直到遇到一个不相等的。然后我们可以将这个不相等的,覆盖到第一个重复元素的位置处,这样子就能在不创建一个临时数组的情况下,直接在原数组进行拷贝了。
遇到这种数组去重,删特定值的时候,并且要求不能有新数组,那么一般可以考虑双指针。
也就是定义两个指针,一个slow指针,表示的是不重复元素下一次可以插入的位置,fast用于遍历数组,找出不重复元素。
这里从下标1开始或者从下标0开始都是可以的。
public int removeDuplicates(int[] nums) {
int n = nums.length;
if (n == 0) {
return 0;
}
int fast = 1, slow = 1;
while (fast< n) {
if (nums[fast] != nums[fast - 1]) {
nums[slow] = nums[fast];
++slow;
}
++fast;
}
return slow;
}
删除特定值既然也是不能创建临时数组,那么就要考虑把特定值给他覆盖掉。
由于要求删除数组中等于 val 的元素,因此输出数组的长度一定小于等于输入数组的长度,我们可以把输出的数组直接写在输入数组上。可以使用双指针:右指针fast指向当前将要处理的元素,左指针slow指向下一个将要赋值的位置。
如果右指针指向的元素不等于 val,它一定是输出数组的一个元素,我们就将右指针指向的元素复制到左指针位置,然后将左右指针同时右移;
如果右指针指向的元素等于 val,它不能在输出数组里,此时左指针不动,右指针右移一位。
也就是,如果遍历的指针(右指针)遇到的值等于val,那么直接忽略,但是如果遇到的值不是,那么就把这个值覆盖到左指针指向的位置。
public int removeElement(int[] nums, int val) {
int slow = 0;//双指针 slow代表的是非val值可以插入的下一个位置
int fast = 0;//fast用于遍历
int n=nums.length;
while (fast
有序数组合并已知两个有序数组,其中第一个有序数组的元素个数为m,第二个有序数组的个数为n。
因此为了能在第一个数组上直接对两个数组进行合并,那么第一个数组的大小应该设定为m+n,也就是合并之后的总大小。
之后,就可以开始考虑如何把两个数组进行合并了。其中第一个数组的尾部的数据均为0,长度为n。
大致如下
输入: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 中的元素。
考虑到当前数组1的尾部有空余元素,因此可以考虑尾插法,从两个数组的有效数据的尾部开始遍历,把更大的数据放在数组的尾部,这样子就能节省一个临时数组了。
// public static void merge(int[] nums1, int m, int[] nums2, int n) {
// for (int i=m,j=0;i= 0 || p2 >= 0) {
if (p1 == -1) {
cur = nums2[p2--];
} else if (p2 == -1) {
cur = nums1[p1--];
} else if (nums1[p1] >nums2[p2]) {
cur = nums1[p1--];
} else {
cur = nums2[p2--];
}
nums1[tail--] = cur;
}
}
链表去重合并算法
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧