顺序表——练习题

题目

1.移除元素

题目链接:27. 移除元素 - 力扣(LeetCode)https://leetcode.cn/problems/remove-element/

题目描述

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。

假设 nums 中不等于 val 的元素数量为 k,要通过此题,您需要执行以下操作:

  • 更改 nums 数组,使 nums 的前 k 个元素包含不等于 val 的元素。nums 的其余元素和 nums 的大小并不重要。

  • 返回 k。

思路一:普通法

创建一个与nums一样的新数组,然后遍历数组nums,将不等于val的值都存入新数组中,最后再用nums替换新数组即可。

代码实现:

int removeElement(int* nums, int numsSize, int val) {
    int* newnums = (int*)malloc(numsSize * sizeof(int)); // 分配内存
    if (newnums == NULL)
        return 0;
    int k=0;
    for(int i=0;i<numsSize;i++)
    {
        if(nums[i]!=val)
        {
            newnums[k]=nums[i];
            k++;
        }
    }
    for(int i=0;i<k;i++)
    {
        nums[i]=newnums[i];
    }
    free(newnums);
    return k;
}

思路二:双指针法

使用双指针法,一个指针src在前面探路,另一个指针dst在后面站岗,图解如下

代码实现:

int removeElement(int* nums, int numsSize, int val) {
    int src=0,dst=0;
    while(src<numsSize)
    {
        if(nums[src]!=val)
        {
            nums[dst]=nums[src];
            dst++;
        }
        src++;
    }
    return dst;
}

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

题目链接:26. 删除有序数组中的重复项 - 力扣(LeetCode)https://leetcode.cn/problems/remove-duplicates-from-sorted-array/description/

题目描述

给你一个 非严格递增排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。

考虑 nums 的唯一元素的数量为 k。去重后,返回唯一元素的数量 k

nums 的前 k 个元素应包含 排序后 的唯一数字。下标 k - 1 之后的剩余元素可以忽略。

这道题和上一道题有些相似,但是有些地方思路也大有不同。

思路一:普通法

创建一个与nums一样的新数组,用两个变量来对比数组nums,然后遍历寻找不一样的元素,将不重复出现的值都存入新数组中,最后再用nums替换新数组即可。

代码实现:

int removeDuplicates(int* nums, int numsSize) {
    int i=0,j=0;
    int k=0;
    int* newnums=(int*)malloc(numsSize*sizeof(int));
    if(newnums==NULL)
    {
        return 0;
    }
    newnums[k++]=nums[j++];
    while(j<numsSize)
    {
        if(nums[i]!=nums[j])
        {
            newnums[k++]=nums[j];
        }
        i++;
        j++;
    }
    for(int n=0;n<k;n++)
    {
        nums[n]=newnums[n];
    }
    return k;
}

这样写下来确实要比思路二“双指针法”麻烦一点,而且也违背了 “原地” 这一规则。

思路二:双指针法

双指针法,图解如下

代码实现:

int removeDuplicates(int* nums, int numsSize) {
    int dst=0,src=dst+1;
    while(src<numsSize)
    {
        if(nums[dst]!=nums[src] && ++dst!=src)//src和dst指向同一个值时不用赋值
        {
            nums[dst]=nums[src];
        }
        src++;
    }
    return dst+1;
}

3.合并两个有序数组

题目链接:88. 合并两个有序数组 - 力扣(LeetCode)https://leetcode.cn/problems/merge-sorted-array/description/

题目描述

给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。

请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。

注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。

思路一:普通法

先合并数组,然后再对合并后的数组排序即可。

代码实现:

int cmp(const void* p1,const void* p2)
{
    return (*(int *)p1-*(int *)p2);
}

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {
    int j=0;
    for(int i=m;i<nums1Size;i++)
    {
        nums1[i]=nums2[j];
        j++;
    }
    qsort(nums1,nums1Size,sizeof(nums1[0]),cmp);
}

思路二:三指针法

用三个变量定位,从后往前遍历两个数组,找大,谁大谁往后放。图解如下:

代码实现:

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--]=nums1[l1--];
        }
        else
        {
            nums1[l3--]=nums2[l2--];
        }
    }
    while(l2>=0)
    {
        nums1[l3--]=nums2[l2--];
    }
}

以上就是我分享的顺序表部分的练习题目了,如果大家有更好的题目欢迎在评论区分享!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值