顺序表小小练习题

在这里插入图片描述

前言

上篇博客学习了线性表之顺序表,模拟实现了顺序表的一些功能。
今天小编为大家奉上有关顺序表的一些题目,慢慢食之。

1、移除元素

习题链接:移除元素

题目

在这里插入图片描述
输入与输出示例:
在这里插入图片描述

思路

这里是简单的对数据进行删除,可以用到我们的顺序表。

思路:双指针写法
本题给定一个数组,需要移除所有和val相同的元素。
它是需要移除与val相同的元素之后,其它元素按照原来顺序存在数组中
这里我想到定义两个标记,left和right,都从下标为 0 开始,遍历整个数组,如果遇到等于val的值,right往前走如果遇到不等与val的值,那就left和right一起往前走,直到遍历完整个数组。

代码

int removeElement(int* nums, int numsSize, int val) 
{  			//   left和right 类似于两个指针一样 遇到指定的情况就往前走
    int n = numsSize;
    int left = 0;   //  第一个标记
    for (int right = 0; right < n; right++) 
    {		//  第二个标记
        if (nums[right] != val) 
        {
            nums[left++] = nums[right];
        }
    }
    return left;
}

小小习题,拿下!!
在这里插入图片描述

2、删除有序数组中的重复项

习题链接:删除有序数组中的重复项

题目

在这里插入图片描述
输入与输出示例:
在这里插入图片描述

思路

本题也是对数据的删除,与上个题目相似,但还是有些许差别。

思路: 双指针写法
本题给一个严格递增的数组,需要删除重复出现的元素,使得每个元素出现一次,并且顺序保持一致。
这里是需要删除掉相同的元素,我觉得双指针的方法屡试不爽,我们还是定义两个指针,left和right这一对好兄弟,遍历整个数组,依旧是right走在前面如果遇到和left对应的值相等,right++如果不相等,判断right与left的间隔,如果right刚好是left的下一个,那就left++,继续循环遍历,如果不是下一个,那就把right指向的值赋值给left+1指向的位置,这样遍历下来,left每走一步都是不一样的数值,我们定义的是数组的下标,所以在返回时需要加1才是元素的个数

代码

int removeDuplicates(int* nums, int numsSize) 
{
    int n = numsSize;
    int left = 0;
    for (int right = 1; right < n; right++) 
    {					
        if (nums[right] != nums[left]) 
        {   			//  当right指向的值与left指向的值不相等时,无论哪种情况,left都需要++
            if (right == ++left)  //  此处简写了   left前置++
                continue;
            else 
            {
                nums[left] = nums[right];
            }
        }
    }
    return left + 1;
}

简简单单又是一题 ^ _ ^

在这里插入图片描述

3、合并两个有序数组

习题链接:合并两个有序数组

题目

在这里插入图片描述
输入输出示例:
在这里插入图片描述

思路

这题就看起来有意思了,将两个有序数组变成一个有序数组。

思路:双指针写法
题目给定两个有序的数组,要将其合并成一个数组并放在数组1中,合并之后也依然有序。在合并过程中涉及到了排序的问题,要判断哪一个数据在前。
我们的双指针好兄弟依然登场,这次不同的是,我们定义一个L1指针指向第一个数组的最后一个位置,一个L2指针指向数组二的最后一个位置,说到这里,想必大家都要猜到我要干嘛,我们从后往前插入一个一个比较,哪个大哪个先放到数组1 (这里的数组1可以看成一个新的数组,我们把两个数组的数据合并到一个新的数组)**,因为题目的数组1给定的长度是两个数组长度之和。从数组结尾遍历到最开始,遍历完之后,基本已经排序完毕,数组也合并完毕。
但是还有一个需要处理的点,就是插入数据都有先后顺序,数组二的数据插入完毕,但是数组一还没有完毕,这时又跳出循环,所以我们需要一个善后处理,下面请康康我滴代码。

代码

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) 
{
    int index = m + n - 1;
    int l1 = m - 1, l2 = n - 1;   //  定义两个指针,分别指向两个数组的最后位置
    while (l1 >= 0 && l2 >= 0) 
    {
        if (nums1[l1] > nums2[l2])    //  哪个大就先插入哪个,然后对应指针往前走
        {
            nums1[index--] = nums1[l1--];
        } 
        else 
        {
            nums1[index--] = nums2[l2--];
        }
    }
    while (l2 >= 0)  //  善后处理  当数组二没插完时  直接一一赋值过去  
    {
        nums1[index--] = nums2[l2--];
    }
}

有点小难度,但还是拿下!!

在这里插入图片描述

总结

今天完成了有关顺序表的一些习题,完成这些,充分感受到双指针的魅力,双指针的印象又进一步加深。同时,对顺序表的认知也更加清晰,对数组的包装与封装。

最后:
很高兴和大家分享自己的一些 小小习题 以及双指针的魅力。
有什么错误的地方,望指出,小编必然及时改正。

在这里插入图片描述

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值