前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >经典的数组和指针结合的OJ题(双指针)

经典的数组和指针结合的OJ题(双指针)

作者头像
用户11316056
发布于 2024-10-16 01:12:37
发布于 2024-10-16 01:12:37
8800
代码可运行
举报
运行总次数:0
代码可运行

一、合并两个有序数组

leetcode链接

题目描述:

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

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

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

思路:

这种将两个有序的数组再合并得到一个全新的有序数组,最直接的办法是先将一个数组的内容拷贝到另一个数组中,然后直接对这个数组进行排序,但是这种方法空间复杂度是O(N),时间复杂度也包含了一个排序的时间,也不见得高效,所以这种思路是不完美的。

另一个思路就是利用了合并算法的思想。

  1. 先将两个指针分别指向两个数组的最小值进行比较
  2. 取较小值的内容放在新的数组
  3. 将取较小值数组的指针向后走一位,继续重复上述的步骤

这种算法的思想的时间复杂度就大大较少,是O(M+N)。

但这一题是变形,题目中将nums1中的数组变长,使之能接收两个数组的元素,也就是说将两个数组合并后的元素全部放在了nums1数组中。思路与上述的合并算法本质是一样的,区别在于我们在两个数组中从后往前找最大值,然后尾插到nums1数组中。

源码:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n)
{
    
    int end1 = m-1;
    int end2 = n-1;
    int num = m+n-1;
    while(end1>=0 && end2>=0)
    {
        if(nums1[end1]<=nums2[end2])
        {
            nums1[num] = nums2[end2];
            end2--;
            num--;
        }
        else
        {
            nums1[num] = nums1[end1];
            end1--;
            num--;
        }
    }
//考虑到当end2>0时,也就是nums2数组没有遍历完毕,我们需要拷贝到nums1数组中
    while(end2>=0)
    {
        nums1[end2]=nums2[end2];
        end2--;
    }
}
小技巧:

在解决问题时,需要考虑不同的情况,也就是不同的样例输出,针对不同的情况去完善代码。

二、移除元素

leetcode链接

题目描述:

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

思路:

利用双指针的思想

  1. 首先将两个指针str、dst一同指向数组的首元素地址
  2. 如果指向的元素是value,那么str++,dst不动;如果指向的元素不是value,先将str指向的内容赋给dst,接着str和dst都向后走一位(核心思想)
  3. 最后返回新数组元素的个数用总个数减去相同元素的次数即可。

这种在空间和时间方面都是双赢,空间复杂度是O(1),时间复杂度是O(N)

源码:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int removeElement(int* nums, int numsSize, int val)
{
    int num = 0;
    int* dst = nums;
    int* str = nums;
    while (str <= nums + numsSize - 1)
    {
        if (*str == val)
        {
            str++;
            num++;
        }
        else
        {
            *dst = *str;
            dst++;
            str++;
        }
    }
    return numsSize-num;
}
小总结:

想要在数组中删除元素并不一定真的删除,可以利用指针去改变数组某些位置的元素,然后打印方式也可以根据指针改变。

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

leetcode链接

题目描述:

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

考虑 nums 的唯一元素的数量为 k ,你需要做以下事情确保你的题解可以被通过:

  • 更改数组 nums ,使 nums 的前 k 个元素包含唯一元素,并按照它们最初在 nums 中出现的顺序排列。nums 的其余元素与 nums 的大小不重要。
  • 返回 k
思路:

同样利用双指针,注意用双指针时,最好直接用整型代表下标,真正用双指针表示双地址还是要麻烦不少

  1. 首先将两个指针指向数组的首元素地址
  2. 若相同,则str++
  3. 不同,先让dst++,然后让dst下标的数组指向的值等于str的值,最后让str++
源码:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int removeDuplicates(int* nums, int numsSize)
{
    int str = 0;
    int dst = 0;
    for(int i = 0;i<numsSize;i++)
    {
        if(nums[str]==nums[dst])
        {
            str++;
        }
        else
        {
            dst++;
            nums[dst]=nums[str];
            str++;
        }
    }
    return dst+1;
}
小总结:

在已知用双指针解决题目后,自己多试几次就会找到及人体方法,重要的是如何知道这题用双指针求解!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-08-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
顺序表在线OJ题(详解+图解)
题目的大概意思是:用户自行输入一个数组,还要输入一个val的整形值,然后从数组中移除等于val的元素 我们根据题目的要求,时间复杂度为O(N)空间复杂度为O(1) 可以用以下的办法: 用一个for循环将数组遍历,再用if语句进行判断,如果不等于val的值,我们就将这个元素放入数组中,如果等于val的话i就继续+1,不放入数组中
ahao
2024/03/19
810
顺序表在线OJ题(详解+图解)
LeetCode刷题(4)【移除元素&合并两个有序数组】(C语言)(含图解)
27. 移除元素 - 力扣(LeetCode) (leetcode-cn.com)
半生瓜的blog
2023/05/12
3520
LeetCode刷题(4)【移除元素&合并两个有序数组】(C语言)(含图解)
移除元素、合并两个有序数组【LeetCode刷题日志】
思路:把每一个数组中的元素与val比较,比较后若元素等于val,则创建一个新的数组,新的数组中删除了这个元素,其他所有元素都往前移一位,此时生成的数组大小为O(n-1)。所以最坏情况是每个元素都是val,则时间复杂度为:
走在努力路上的自己
2024/01/26
1340
移除元素、合并两个有序数组【LeetCode刷题日志】
力扣之顺序表
学完复杂度之后,算是正式进入到数据结构的学习。至此我们将首先了解顺序表的有关知识,包括增删查改等接口函数及其思想。顺序表其实就是数组,它要求数据在内存中必须是连续存储的。本文主要介绍力扣的三道顺序表的习题,这些习题主要利用双指针的思想来解决。
始终学不会
2023/03/28
1540
力扣之顺序表
【数据结构初阶】顺序表的实现
线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串… 线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。 我们的顺序表和链表就分别是以数组和链式结构进行存储的
举杯邀明月
2023/04/12
3190
【数据结构初阶】顺序表的实现
【OJ】关于顺序表的经典题目(移除数组中指定元素的值、数组去重、合并两个有序的数组)
那么在本文中,我们将会给出几道有关于顺序表(个人觉得于数组的相关性较大)经典的代码练习题,并且总结一些做题的经验,呈现给大家。
埋头编程
2024/10/16
800
【OJ】关于顺序表的经典题目(移除数组中指定元素的值、数组去重、合并两个有序的数组)
【剑指offer|3.合并两个有序的数组】
0.合并两个有序数组 题意:有两个排好升序的数组A1,A2,内存在A1的末尾有足够多的空余位置容纳A2,请实现一个函数,把A2中所有的数字插入到A1中,并且所有的数字都是排序的。 nums1.length == m + n nums2.length == n 题解:本题和【剑指offer|2.替换空格】类似,由于在合并数组(字符串)时,如果从前往后移动每一个数字都需要重复移动数字多次,因此我们可以考虑从后往前移动,从而提高效率。 1.C语言版 void merge(int* nums1, i
MicroFrank
2023/04/09
3030
【剑指offer|3.合并两个有序的数组】
数组相关面试题--5.合并两个有序数组
绝活蛋炒饭
2024/12/16
1060
数组相关面试题--5.合并两个有序数组
两道关于顺序表的经典算法
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
南桥
2024/01/26
1360
两道关于顺序表的经典算法
【初阶数据结构与算法】沉浸式刷题之顺序表练习(顺序表以及双指针两种方法)
   在顺序表练习中我们会首先使用我们学过的顺序表来解决,然后再同时介绍一下其它方法,在练习开始之前我们要说明一个东西,就是我们之前不是写好了一个顺序表吗?我们等一下就直接全部复制过来用    那么是不是就说明我们以后要用数据结构做题就必须把它手写一遍吗?这是不需要的,后面我们会介绍C++,在C++中的STL中有现成的可以用,现在我们还没有介绍到,就复制我们写过的数据结构来做题    在做题过程中,我们也会计算这些方法的时间复杂度和空间复杂度,也是对之前内容的一个复习
TANGLONG
2024/11/19
890
【初阶数据结构与算法】沉浸式刷题之顺序表练习(顺序表以及双指针两种方法)
【数据结构初阶】顺序表三道经典算法题(详解+图例)
上面的例子第一个数是等于val,当不等于val 时可以自己试一下。新思路的时间复杂度为O(N),空间复杂度为O(N),结合思路我们尝试上代码:
云边有个稻草人
2024/10/21
1050
【数据结构初阶】顺序表三道经典算法题(详解+图例)
【顺序表】算法题 --- 力扣
这个题让我们移除数组nums中值为val的元素,最后返回k(不是val的元素个数)
星辰与你
2024/10/17
860
【顺序表】算法题 --- 力扣
刷题日记 ---- 顺序表与链表相关经典算法题(C语言版)
题目明确要求, 不能使用额外的数组空间, 也就是说不可以创建一个新的数组. 可以使用双指针法, 一个指向源数组, 一个指向目标数组, 定义两个下标, 分别从第一个元素开始向后遍历, 当src所在位置的数组值等于val时, 跳过此元素, 当src指向的数组不等于val值时, 将src位置的元素存放到dst位置, 继续向后遍历, 当遍历到数组结尾, 跳出循环, 此时dst内存放的就是不含val值的数组.
用户11317877
2024/10/16
780
刷题日记 ---- 顺序表与链表相关经典算法题(C语言版)
leetcode 双指针算法专题
双指针是一种方法,一种思想一种技巧,也谈不上什么特别的算法,在二分查找中经常使用这个技巧,具体就是用两个变量动态的存储两个或者多个的结点,来方便我们进行一些操作,通常使用在线性结构中,比如说数组或者是链表。 在我们遇到像数组,链表这类数据结构的算法题目的时候,应该要想得到双指针的来解决问题。特别是链表类的题目,经常需要用到两个或多个指针配合来记忆链表上的节点,完成某些操作。链表这种数据结构也是树形结构和图的原型,所以有时候在关于图和树形结构的算法题目中也会用到双指针。
Albert_xiong
2021/06/21
5480
leetcode 双指针算法专题
LeetCode-双指针
使用双指针,一个指针指向值较小的元素,一个指针指向值较大的元素。指向较小元素的指针从头向尾遍历,指向较大元素的指针从尾向头遍历。
LittlePanger
2020/04/14
5250
【数据结构副本篇】顺序表 链表OJ
学习其实和打游戏一样,当你觉得BOSS难打的时候就说明是你的等级和装备不够,此时就需要我们多去刷刷副本,增加一点经验,顺便爆点装备出来,提升自己,从而轻松搞定BOSS
f狐o狸x
2024/11/19
350
【数据结构副本篇】顺序表 链表OJ
了解单链表
思路一: 创建新的数组,遍历原数组,将不为val的值放到新数组当中。空间复杂度不为O(1)
用户11039545
2024/04/15
920
了解单链表
与双指针的亲密接触:快与慢的浪漫交错
给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n,分别表示 nums1 和 nums2 中的元素数目。
凯子坚持C
2024/10/17
690
与双指针的亲密接触:快与慢的浪漫交错
【C语言】Leetcode 88.合并两个有序数组
要注意的地方是在转移的最后剩余的是nums1还是nums2,因为是往nums1中添加,所以是nums1时不会产生影响。当剩余的是nums2时,由于添加的时候是按大的往进添加,而且nums1和nums2都是有序数组,所以剩余的nums2一定也是小于nums1的,按逻辑继续添加就可以正常实现。
DevKevin
2024/03/19
1520
【C语言】Leetcode 88.合并两个有序数组
顺序表、链表相关OJ题(1)
本文为经典算法OJ题练习,大部分题型都有多种思路,每种思路的解法博主都试过了(去网站那里验证)是正确的,大家可以参考!!
小陈在拼命
2024/02/17
1230
顺序表、链表相关OJ题(1)
相关推荐
顺序表在线OJ题(详解+图解)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文