欢迎光临
我们一直在努力

用双指针法解决两道顺序表基础算法题(LeetCode 27 & 88)

LeetCode 27. 移除元素

我们要在数组nums中寻找所有值为val的元素,将它们删除并返回数组中剩下的元素个数。

解题思路

首先想到的是创建一个临时数组,把需要留下的数据放进去,然后再复制回nums。不过这样有点麻烦。

我们可以用双指针法来解决这个问题。

所谓“双指针”并不是两个指针变量,而是两个整型变量。只是我们让它们代表数组元素的下标,仿佛指向了数组中的元素。

我们创建这样的两个整型变量:src(source)和dst(destination)。刚开始src和dst同时指向数组nums的起始位置:

接着我们判断src指向的元素的值是否为val,做如下操作:

1)如果src指向的值为val,则src++,也就是让src向后移动一位。

2)如果src指向的值不为val,则nums[dst] = nums[src],src++,dst++。也就是将src指向的位置的值赋给dst指向的位置,再让src和dst同时向后移动一位。

这样,当src遍历了数组中的所有元素之后,所有值为val的元素就都被删除了,而dst就是数组中剩余的元素个数。

代码

int removeElement(int* nums, int numsSize, int val)
{
//先创建两个变量
int src,dst;
src = dst = 0;
while(src < numsSize)
{
if(nums[src] == val)
{
src++;
}
else
{
//赋值,两变量++
nums[dst] = nums[src];
src++;
dst++;
}
}
return dst;
}

LeetCode 88. 合并有序数组

题目要求我们将两个升序排列的数组合并,结果储存在第一个数组中。 

解题思路

思路1:将nums2中的数据依次放到nums1数组的后面,用排序算法对nums1进行排序。

不足:如果借助效率低下的排序算法,会降低整体运行效率。而且,我们这样做等于是浪费了给出的两个数组都是有序的这个条件。

我们仍然可以用双指针法来解决这个问题。

如图,我们创建三个整型变量。我们让l1、l2分别指向已有的两组数据的最后一个数,l3指向num1的最后一个元素。

我们让l1和l2指向的数据进行比较。那个数大我们就把哪个数赋给l3指向的位置,再让l3和大的那个数对应的“指针”向前移一位。

重复以上步骤:

此时我们发现 l1先出循环(先变为<0的值),意味着num2中还有数据没有放到nums1中,我们只需循环把nums2中数据放到nums1中就好了。

而如果是l2先出循环,那么说明nums2中所有数据都已经放到nums1中,我们就不用再进行操作了。

代码

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n)
{
int l1 = m – 1;
int l2 = n – 1;
int l3 = m + n – 1;
while(l1 >= 0 && l2>=0)
{
if(nums1[l1] < nums2[l2])
{
//nums1[l3] = nums2[l2];
//l2–;
//l3–;
nums1[l3–] = nums2[l2–];
}
else
{
nums1[l3–] = nums1[l1–];
}
}

while(l2>=0)
{
nums1[l3–] = nums2[l2–];
}
}

总结

这两道题是顺序表非常经典的两道基础题。二者均围绕数组内存连续、支持随机访问、原地操作的特性展开,核心思想高度统一:都采用双指针法在原数组上完成操作。掌握这两道题,不仅能深刻理解数组的本质特点,更能熟练运用双指针这一通用思路,为后续更复杂的数组、链表、滑动窗口等算法题目打下扎实基础。

赞(0)
未经允许不得转载:171主机测评 » 用双指针法解决两道顺序表基础算法题(LeetCode 27 & 88)
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址