(C语言版)力扣(LeetCode)数组相关面试题OJ题解析

news2024/9/29 13:16:22

在这里插入图片描述

数组相关面试题

  • 26. 删除有序数组中的重复项
    • 题目
    • 说明
    • 示例一
    • 示例二
    • 提示
    • 解析
  • 27.移除元素
    • 题目
    • 说明
    • 示例1
    • 示例2
    • 提示
    • 解析
      • 解法一
      • 解法二
  • 88. 合并两个有序数组
    • 题目
    • 示例一
    • 示例二
    • 示例三
    • 提示
    • 解析
  • 结语

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

题目

给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。
考虑 nums 的唯一元素的数量为 k ,你需要做以下事情确保你的题解可以被通过:
★更改数组 nums ,使 nums 的前 k 个元素包含唯一元素,并按照它们最初在 nums 中出 现的顺序排列。nums 的其余元素与 nums 的大小不重要。
★返回 k 。
题目链接:删除有序数组中的重复项

说明

系统会用下面的代码来测试你的题解:

int[] nums = [...]; // 输入数组
int[] expectedNums = [...]; // 长度正确的期望答案

int k = removeDuplicates(nums); // 调用

assert k == expectedNums.length;
for (int i = 0; i < k; i++) {
    assert nums[i] == expectedNums[i];
}

如果所有断言都通过,那么您的题解将被通过。

示例一

输入:nums = [1,1,2]
输出:2, nums = [1,2,_]
解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。

示例二

输入:nums = [0,0,1,1,1,2,2,3,3,4]
输出:5, nums = [0,1,2,3,4]
解释:函数应该返回新的长度 5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。

提示

1 <= nums.length <= 3 * 104
-104 <= nums[i] <= 104
nums 已按 升序 排列

解析

代码如下:

int removeDuplicates(int* nums, int numsSize) {
    if (numsSize == 0) {
        return 0;
    }
    int fast = 1, slow = 1;
    while (fast < numsSize) {
        if (nums[fast] != nums[fast - 1]) {
            nums[slow] = nums[fast];
            ++slow;
        }
        ++fast;
    }
    return slow;
}

这种写法是采用双指针的写法,fast指针和slow指针都是从第二个元素开始,若fast指向的元素等于前一个元素,则fast向前一步,直到找到不等于fast前一个元素,则将fast此时指向的元素赋给slow指向的元素位置,slow向前一步,直至fast指针遍历完整个数组,返回slow即为有效前n位。
例如:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

27.移除元素

题目

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
题目链接:移除元素

说明

为什么返回数值是整数,但输出的答案是数组呢?
请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
你可以想象内部操作如下:

// nums 是以“引用”方式传递的。也就是说,不对实参作任何拷贝
int len = removeElement(nums, val);

// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。
for (int i = 0; i < len; i++) {
    print(nums[i]);
}

示例1

输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。

示例2

输入:nums = [0,1,2,2,3,0,4,2], val = 2
输出:5, nums = [0,1,4,0,3]
解释:函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。注意这五个元素可为任意顺序。你不需要考虑数组中超出新长度后面的元素。

提示

0 <= nums.length <= 100
0 <= nums[i] <= 50
0 <= val <= 100

解析

解法一

代码如下:

int removeElement(int* nums, int numsSize, int val) {
    int left = 0;
    for (int right = 0; right < numsSize; right++) {
        if (nums[right] != val) {
            nums[left] = nums[right];
            left++;
        }
    }
    return left;
}

这种解法采用的是双指针的方法,当right指针等于val值时,right指针向后移动,left指针不变,而right指针不等于val时,将此时right指向的值赋给left指向的元素位置(left此时指向的是等于val值的元素),直至right遍历整个数组为止,此时返回left指针指向的位置,前left个元素都为不等于val值的元素,符合题意。
简化后代码如下:

int removeElement(int* nums, int numsSize, int val)
{
int left=0;
for(int right=0;right<numsSize;right++)
{
    if(nums[right] !=val )
    nums[left++]=nums[right];
}
return left;
}

例如:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

解法二

代码如下:

int removeElement(int* nums, int numsSize, int val) {
    int left = 0, right = numsSize-1;
    while (left <= right) {
        if (nums[left] == val) {
            nums[left] = nums[right];
            right--;
        } else {
            left++;
        }
    }
    return left;
}

这种写法采用的是前后指针的写法,left指向第一个元素,right指向最后一个元素,,如果left指向的元素等于val值,则将right指向的元素赋给left指向元素位置,right指针向后一步,不等于,则left向前一步,最后,left大于right值结束循环,返回下标+1的值,即有效元素个数。

88. 合并两个有序数组

题目

给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。
请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。
注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。

示例一

输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
解释:需要合并 [1,2,3][2,5,6] 。
合并结果是 [1,2,2,3,5,6] ,其中斜体加粗标注的为 nums1 中的元素。

示例二

输入:nums1 = [1], m = 1, nums2 = [], n = 0
输出:[1]
解释:需要合并 [1][] 。
合并结果是 [1]

示例三

输入:nums1 = [0], m = 0, nums2 = [1], n = 1
输出:[1]
解释:需要合并的数组是 [][1] 。
合并结果是 [1] 。
注意,因为 m = 0 ,所以 nums1 中没有元素。nums1 中仅存的 0 仅仅是为了确保合并结果可以顺利存放到 nums1 中。

提示

nums1.length == m + n
nums2.length == n
0 <= m, n <= 200
1 <= m + n <= 200
-109 <= nums1[i], nums2[j] <= 109

解析

代码如下:

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){
        int i = m - 1, j = n - 1, k = m + n - 1;
        while (j >= 0)
         {
            if (i < 0 || nums2[j] > nums1[i]) 
                nums1[k--] = nums2[j--];
            else 
                nums1[k--] = nums1[i--];
         }
}

这种写法是最为简洁且更好理解的一种,所以这里不采用官方的推荐写法,为了更方便大部分人理解。首先设定i为nums1数组有效元素的下标上界,j为nums2数组有效元素的下标上界,k为合并后数组有效元素的下标上界。判断条件是从两个数组有效元素最后一位开始比较,谁大将谁放进数组最后(i<0这个条件是nums1中的元素全部向后填充完毕,但nums2种还有剩余元素的情况),依次递减,最后合并完毕。
例如:
上面是nums1,下面是nums2
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

结语

这里的解法代码部分来自力扣官方和作者自己的解法,作者只是进行了详细的剖析和部分改动方便大家理解和提升自己,学会多角度观察问题,解决问题。

有兴趣的小伙伴可以关注作者,如果觉得内容不错,请给个一键三连吧,蟹蟹你哟!!!
制作不易,如有不正之处敬请指出
感谢大家的来访,UU们的观看是我坚持下去的动力
在时间的催化剂下,让我们彼此都成为更优秀的人吧!!!
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/486086.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Verilog HDL——Modelsim仿真

常用testbench语法 $finish 和 $stop &#xff1a; $finish任务用于终止仿真并跳出仿真器&#xff1b;$stop任务则用于中止仿真。timescale [time_unit] / [time_precision] &#xff1a;time_unit指定计时和延时的测量单位&#xff0c;time_precision则是指定仿真器的精度。#…

7.3 有源滤波电路(1)

对信号的频率具有选择性的电路称为滤波电路&#xff0c;它的功能是使特定频率范围内的信号通过&#xff0c;而阻止其它频率信号通过。有源滤波电路是应用广泛的信号处理电路。 一、滤波电路的基础知识 1、滤波电路的种类 通常&#xff0c;按照滤波电路的工作频带为其命名&am…

C语言从入门到精通第17天(指针和数组联用)

指针和数组联用 不同类型指针变量之间的区别数组的指针指针数组 不同类型指针变量之间的区别 在了解数组和指针联用之前&#xff0c;我们先对指针变量进行补充。我们对比一下int *p1和char *p2的区别&#xff1f; 相同点&#xff1a; 都是指针变量都是用来保存一个内存地址编…

中级软件设计师备考---软件工程1

目录 经典的模型敏捷开发方法【的分类】信息系统开发方法【的分类】结构化设计---内聚与耦合结构化设计---系统结构/模块结构 需求的分类 经典的模型 瀑布模型&#xff1a;最早的一类、适用于需求明确的项目、结构化的典型代表 原型模型&#xff1a;先构造一个建议的系统原型再…

数据治理服务及数据治理应用解决方案

本资料来源公开网络&#xff0c;仅供个人学习&#xff0c;请勿商用&#xff0c;如有侵权请联系删除。 一、数据治理概述 (一) 数据治理概念 数据治理是指将数据作为组织资产围绕数据全生命周期而展开的相关管控活动、绩效和风险管理工作的集合&#xff0c;以保障数据及其应用…

Nmap入门到高级【第十章】

预计更新Nmap基础知识 1.1 Nmap简介和历史 1.2 Nmap安装和使用方法 1.3 Nmap扫描技术和扫描选项 Nmap扫描技术 2.1 端口扫描技术 2.2 操作系统检测技术 2.3 服务和应用程序检测技术 2.4 漏洞检测技术 Nmap扫描选项 3.1 扫描类型选项 3.2 过滤器选项 3.3 探测选项 3.4 输出选项…

中间件漏洞(二)nginx解析漏洞

目录 1.漏洞原理分析 2. 利用条件 3. 漏洞复现 1.漏洞原理分析 Nginx的解析漏洞的出现和Nginx的版本没有关系&#xff0c;漏洞的产生是由于php配置问题导致的。 2. 利用条件 # php.ini cgi.fix_pathinfo1 # php-fpm.conf security.limit_extensions 分别解释一下cgi.fix_…

Sentinel --- 隔离和降级、授权规则、规则持久化

一、隔离和降级 限流是一种预防措施&#xff0c;虽然限流可以尽量避免因高并发而引起的服务故障&#xff0c;但服务还会因为其它原因而故障。 而要将这些故障控制在一定范围&#xff0c;避免雪崩&#xff0c;就要靠线程隔离&#xff08;舱壁模式&#xff09;和熔断降级手段了…

HTTP加密

文章目录 原理方式证书 原理 HTTP HTTPS TLS/SSL&#xff08;数据的加密解密层&#xff09; HTTP是应用层的协议&#xff0c;当应用层向下访问的时候并不是直接访问到socket层&#xff0c;而是先通过TLS/SSL加密解密层后再进行后续工作。此时得到的协议就是HTTPS。 举个例…

【五一创作】排序篇:冒泡排序,快速排序的递归与非递归实现(C语言)

目录 前言&#xff1a; 一&#xff1a;冒泡排序 基础思路 完整排序 时间复杂度分析 二&#xff1a;递归实现快速排序 基础思路 单趟排序 (1)双向扫描法 (2)挖坑法 (3)前后指针法(推荐这种) 完整排序 时间复杂度分析 优化 (1)三数取中 (2)小区间优化 三&#xf…

基于Vue3+TS+Vite+Cesium创建项目

基于Vue3TSViteCesium创建项目 基于Vite构建项目安装配置Cesium创建Cesium三维视图运行结果 随着近几年社会的发展&#xff0c;人们对三维可视化的需求也是越来越多&#xff0c;三维GIS如今真的越来越火了&#xff0c;对于做GIS前端开发的人员来说&#xff0c;Cesium开发是绝对…

PLC模糊PID(模糊规则表)

模糊PID的模糊化相关内容,请参看下面的博客文章: PLC模糊控制模糊PID(梯形图实现+算法分析)_RXXW_Dor的博客-CSDN博客博途PLC的模糊PID控制详细内容请查看下面的博客文章:Matlab仿真+博途PLC模糊PID控制完整SCL源代码参考(带模糊和普通PID切换功能)_博途怎么实现模糊pid_…

linux驱动开发 - 08_内核定时器

文章目录 1 Linux 时间管理和内核定时器简介1.1 内核时间管理简介1.2 内核定时器简介1、init_timer 函数2、add_timer 函数3、del_timer 函数4、del_timer_sync 函数5、mod_timer 函数 1.3 Linux 内核短延时函数 2 实验程序编写2.1 定时器驱动程序编写2.2 编写测试 APP 3 编译驱…

【Linux】管道

目录 一、前言 二、管道 1、匿名管道 1.1、基本原理 1.2、代码实现 1.3、管道的特点 1.4、基于管道的简单设计 2、命名管道 2.1、匿名管道与命名管道的区别 2.2、代码实现命名管道通信 一、前言 为了满足各种需求&#xff0c;进程之间是需要通信的。进程间通信的主要目…

【VM服务管家】专题_7.5 异常收集

目录 5.1 信息收集&#xff1a;异常报错信息收集的方法5.2 日志等级&#xff1a;日志等级调低的方法 5.1 信息收集&#xff1a;异常报错信息收集的方法 描述 环境&#xff1a;VM4.0以上VS2013及以上 现象&#xff1a;未知问题、偶发问题、崩溃问题如何收集信息提供给研发排查。…

【Linux】基础IO——库函数与系统调用的关系

目录 引言1.文件操作语言方案&#xff08;C的文件操作接口-库函数&#xff09;打开文件、关闭文件——fopen、fclose打开文件的模式 写入——fput、printf读取——fgets 2.文件操作系统方案&#xff08;系统的文件操作接口-系统调用&#xff09;打开文件、关闭文件——open、cl…

【游戏逆向】Lua游戏逆向及破解方法介绍

前言 随着手游的发展&#xff0c;越来越多的Cocos-lua端游开发者转移到手游平台。Lua脚本编写逻辑的手游也是越来越多&#xff0c;如梦幻西游、刀塔传奇、开心消消乐、游龙英雄、奇迹暖暖、疾风猎人、万万没想到等手游。随着Lua手游的增加&#xff0c;其安全性更值得关注&…

python基本数据类型---数字字符串

引入 在内存中存储的数据可以是不同的数据类型。比如名字可以使用字符串存储&#xff0c;年龄可以使用数字存储&#xff0c;python有6种基本数据类型&#xff0c;用于各种数据的存储&#xff0c;分别是&#xff1a;numbers(数字类型)、string(字符串)、List(列表)、Tuple(元组…

哈希表企业应用-DNA的字符串检测

DNA的字符串检测-引言 若干年后, ikun DNA 检测部成立,专门对 这些ikun的解析检测 突然发现已经完全控制不了 因为学生已经会了 而且是太会了 所以DNA采用 以下视频测试: ikun必进曲 ikun必经曲 ikun必阶曲 如何感受到了吧!,如果你现在唱跳并且还Rap 还有打篮球 还有铁山靠 那…

自动化运维工具Ansible之playbooks剧本

目录 一、playbooks 1、playbooks简述 2、playbooks剧本格式 3、playbooks组成部分 4、playbooks启动及检测 5、playbooks模块实战实例1 6、vars模块实战实例2 7、when模块实战实例3 8、with_items循环模块实战实例4 9、template模块实战实例5 10、tags模块实战实例…