自解代码示例:
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
int i=m-1,j=n-1;
int p=m+n-1;
while(i>=0 && j>=0){
if(nums1[i]>nums2[j]){
nums1[p]=nums1[i];
p--;
i--;
}else{
nums1[p]=nums2[j];
p--;
j--;
}
}
while(i>=0){
nums1[p]=nums1[i];
i--;
p--;
}
while(j>=0){
nums1[p]=nums2[j];
j--;
p--;
}
}
}
当数组均非空时,对于nums1采用倒插法;当有一个为空时只需关注一个进行插入。
刷题插件的解题思路:
对于单链表来说,直接用双指针从头开始合并即可,但对于数组来说会出问题。因为题目让直接把结果存到 nums1
中,而 nums1
的开头有元素,如果我们无脑复制单链表的逻辑,会覆盖掉 nums1
的原始元素,导致错误。
但 nums1
后面是空的,所以这道题需要我们稍微变通一下:将双指针初始化在数组的尾部,然后从后向前进行合并,这样即便覆盖了 nums1
中的元素,这些元素也必然早就被用过了,不会影响答案的正确性。
因为本题中的nums1中的数组长度刚好可以装下两个数组的所有元素,所以代码中是
int p = nums1.length - 1;
若不能装下所有元素时,只需将p的值换成两个数组元素之和即可。
解法代码
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--;
}
}
}
力扣官方解析:
将数组nums2放入数组nums1的尾部,然后直接对整个数组进行排序。
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
for (int i = 0; i != n; ++i) {
nums1[m + i] = nums2[i];
}
Arrays.sort(nums1);
}
}
该方法运用了sort排序方法
sort()方法根据指定的顺序对动态数组中的元素进行排序。
sort()方法的语法为:
arraylist.sort(Comparator c);
//注:arraylist是ArrayList类的一个对象。
//菜鸟教程
Arrays.sort方法用来对数组排序。Collections.sort()方法用来对链表排序,而Collections.sort()的底层,其实使用的也是Arrats.sort方法。
自解代码示例:
class Solution {
public int removeElement(int[] nums, int val) {
int count = 0,len = nums.length;
for(int i=0; i<len;i++ ){
if(nums[i]!=val){
nums[count]=nums[i];
count++;
}
}
return count;
}
};
一开始报错的原因是忘记写返回值,因为public int removeElement中是int,所以一定会有返回值不要忘记。
确定数组长度大小的采用的是length;本题想法考虑的就是把数组下标重新进行变换,从0开始,将符合条件的赋予新的下标,反之略过;需要注意的一点是无论新的数组下标还是旧的数组下标都需要保证下标是运动的而非静止的。