顺序表和链表面试题
文章目录
- 顺序表
- (1)原地移除数组中所有的元素val,要求时间复杂度为O(N),空间复杂度为O(1)。
- (2)删除有序数组中的重复项
- (3)合并两个有序数组
- 链表
- (1)删除链表中等于给定值 val 的所有节点
- (2)反转一个单链表
- (3) 合并两个有序链表
- (4)链表的中间结点
- (5)链表中倒数第k个结点
- (6)分割链表
- (7)输入两个链表,找出它们的第一个公共结点(Y型)
- (8)给你一个链表的头节点 head ,判断链表中是否有环。
- (9)给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
- (10)判定链表是否是回文
顺序表
(1)原地移除数组中所有的元素val,要求时间复杂度为O(N),空间复杂度为O(1)。
oj链接
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并原地修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
双指针
class Solution {public int removeElement(int[] nums, int val) {int left = 0;for (int right = 0; right < nums.length; right++) {if (nums[right] != val) {nums[left++] = nums[right];}}return left;}
}
(2)删除有序数组中的重复项
oj链接
给你一个 非严格递增排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。
考虑 nums 的唯一元素的数量为 k ,你需要做以下事情确保你的题解可以被通过:
更改数组 nums ,使 nums 的前 k 个元素包含唯一元素,并按照它们最初在 nums 中出现的顺序排列。nums 的其余元素与 nums 的大小不重要。
返回 k
双指针
class Solution {public int removeDuplicates(int[] nums) {if(nums == null || nums.length == 0) return 0;int front = 0;int next = 1;while(next < nums.length){if(nums[front] != nums[next]){nums[++front] = nums[next];}next++;}return front+1;}
}
优化(相邻的元素不同不进行多余的赋值操作)
像[1,2,3,4,5]就不用进行赋值操作
class Solution {public int removeDuplicates(int[] nums) {if(nums == null || nums.length == 0) return 0;int front = 0;int next = 1;while(next < nums.length){if(nums[front] != nums[next]){if(next - front > 1){nums[front + 1] = nums[next];}front++;}next++;}return front + 1;}
}
(3)合并两个有序数组
oj链接
给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。
请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。
注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。
从后面开始确定
class Solution {public void merge(int[] nums1, int m, int[] nums2, int n) {while(m>0&&n>0) {if(nums1[m-1]>nums2[n-1]) {nums1[m+n-1] = nums1[m-1];m--;} else {nums1[m+n-1] = nums2[n-1];n--;}}while(n>0) {nums1[n-1] = nums2[n-1];n--;}}
}
链表
(1)删除链表中等于给定值 val 的所有节点
oj链接
给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
class Solution {public ListNode removeElements(ListNode head, int val) {while(head!=null&&head.val==val) {head= head.next;}if(head == null) {return null;}ListNode prev = head;while(prev.next!=null) {if(prev.next.val==val) {prev.next=prev.next.next;} else {prev=prev.next;}}return head;}
}
(2)反转一个单链表
oj链接
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
class Solution {public ListNode reverseList(ListNode head) {if(head==null) return null;ListNode prev = null;ListNode cur = head;ListNode next = head.next;while(next != null) {cur.next = prev;prev = cur;cur = next;next = next.next;}cur.next = prev;return cur;}
}
递归
class Solution {public ListNode reverseList(ListNode head) {if (head == null || head.next == null) {return head;}ListNode newHead = reverseList(head.next);head.next.next = head;head.next = null;return newHead;}
}
(3) 合并两个有序链表
oj链接
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
class Solution {public ListNode mergeTwoLists(ListNode l1, ListNode l2) {ListNode prehead = new ListNode(-1);ListNode prev = prehead;while (l1 != null && l2 != null) {if (l1.val <= l2.val) {prev.next = l1;l1 = l1.next;} else {prev.next = l2;l2 = l2.next;}prev = prev.next;}prev.next = l1 == null ? l2 : l1;return prehead.next;}
}
递归
class Solution {public ListNode mergeTwoLists(ListNode l1, ListNode l2) {if (l1 == null) {return l2;}else if (l2 == null) {return l1;}else if (l1.val < l2.val) {l1.next = mergeTwoLists(l1.next, l2);return l1;}else {l2.next = mergeTwoLists(l1, l2.next);return l2;}}
}
(4)链表的中间结点
oj链接
给你单链表的头结点 head ,请你找出并返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。
快慢指针
慢指针走一步,快指针走两步
while循环条件不能换顺序
class Solution {public ListNode middleNode(ListNode head) {ListNode fast = head;ListNode slow = head;while(fast!=null&&fast.next!=null) {fast = fast.next.next;slow = slow.next;}return slow;}
}
(5)链表中倒数第k个结点
牛客网链接
输入一个链表,输出该链表中倒数第k个结点。
public class Solution {public ListNode FindKthToTail(ListNode head,int k) {ListNode fast = head;ListNode slow = head;if(k<=0||head==null) return null;while(k-1>0) {if(fast.next == null) return null;fast = fast.next;k--;}while(fast.next!= null) {fast = fast.next;slow = slow.next;}return slow;}
}
(6)分割链表
oj链接
给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在大于或等于 x 的节点之前。
你不需要 保留 每个分区中各节点的初始相对位置。
class Solution {public ListNode partition(ListNode head, int x) {if(head==null) return null;ListNode less = new ListNode(-1);ListNode lessHead = less;ListNode larger = new ListNode(-1);ListNode largerHead = larger;while(head != null) {if(head.val<x) {less.next = head;less = less.next;} else {larger.next = head;larger = larger.next;}head = head.next;}larger.next = null;less.next = largerHead.next;return lessHead.next;}
}
方法二:
class Solution {public ListNode partition(ListNode head, int x) {ListNode cur = head;ListNode bs = null;ListNode be = null;ListNode as = null;ListNode ae = null;//使用cur来遍历 所有的节点while (cur != null) {if (cur.val < x) {if (bs == null) {bs = cur;be = cur;} else {be.next = cur;be = be.next;}} else {// >= xif (as == null) {as = cur;ae = cur;} else {ae.next = cur;ae = ae.next;}}cur = cur.next;}if (bs == null) {return as;}be.next = as;if (as != null) {ae.next = null;}return bs;}
}
如果bs为null,那么原链表最后一个节点(next是null)是ae,ae的next就不用置为null
(7)输入两个链表,找出它们的第一个公共结点(Y型)
oj链接
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。
图示两个链表在节点 c1 开始相交:
public class Solution {public ListNode getIntersectionNode(ListNode headA, ListNode headB) {if (headA == null || headB == null) {return null;}ListNode pA = headA, pB = headB;while (pA != pB) {pA = pA == null ? headB : pA.next;pB = pB == null ? headA : pB.next;}return pA;}
}
(8)给你一个链表的头节点 head ,判断链表中是否有环。
oj链接
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。
如果链表中存在环 ,则返回 true 。 否则,返回 false 。
思路
快慢指针,即慢指针一次走一步,快指针一次走两步,两个指针从链表起始位置开始运行,如果链表带环则一定会在环中相遇,否则快指针走到链表的末尾。
为什么快指针每次走两步,慢指针走一步可以?
假设链表带环,两个指针最后都会进入环,快指针先进环,慢指针后进环。当慢指针刚进环时,可
能就和快指针相遇了,最差情况下两个指针之间的距离刚好就是环的长度。此时,两个指针每移动
一次,之间的距离就缩小一步,不会出现每次刚好是套圈的情况,因此:在慢指针走到一圈之前,
快指针肯定是可以追上慢指针的,即相遇。
public class Solution {public boolean hasCycle(ListNode head) {ListNode fast = head;ListNode slow = head;while(fast != null && fast.next !=null) {fast = fast.next.next;slow = slow.next;if(fast == slow) {return true;}}return false;}
}
(9)给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
oj链接
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表。
思路
设链表头部走x步到环的入口, 环有 y 个节点(包括环入口节点)
先跟上一题一样, fast走两步,slow走一步,如果有环的话在环中相遇.
设在环中走了s步(不包括环的入口节点)
那么slow走了x+s步
fast走了x+s+ny(n是圈数)
因为fast走的距离是slow的两倍
所以2(x+s) = x+s+ny
即x=(n-1)*y+(y-s)
让fast从起始位置走,slow从相遇的位置走(n-1)*y+y-s步,他们会在环的入口相遇.
public class Solution {public ListNode detectCycle(ListNode head) {ListNode fast = head;ListNode slow = head;while(fast != null && fast.next !=null) {fast = fast.next.next;slow = slow.next;if(fast == slow) {fast = head;while(fast != slow) {fast = fast.next;slow = slow.next;}return fast;}}return null;}
}
(10)判定链表是否是回文
即正读和倒读一样的链表
牛客网链接
对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。
给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。
思路
先用快慢指针找到中间节点(奇数中间,偶数第二个中间结点),将中间节点之后的节点反转,一头从头结点,一头从末尾结点开始比较.
奇数的情况
当两个指针相遇的时候返回true
偶数的情况
当第一个节点的下一个节点是第二个节点且相等就返回true
public class PalindromeList {public boolean chkPalindrome(ListNode A) {if(A==null) {return true;}ListNode fast = A;ListNode slow = A;while(fast!=null&&fast.next!=null) {fast = fast.next.next;slow = slow.next;}ListNode prev = slow;ListNode cur =slow.next;while(cur!=null) {ListNode next = cur.next;cur.next = prev;prev = cur;cur = next;}while(A!=slow) {if(A.val!=prev.val) {return false;}//偶数的情况if(A.next==prev) {return true;}A=A.next;prev=prev.next;}return true;}
}
相关文章:
顺序表和链表面试题
文章目录 顺序表(1)原地移除数组中所有的元素val,要求时间复杂度为O(N),空间复杂度为O(1)。(2)删除有序数组中的重复项(3)合并两个有序数组 链表(1)删除链表中等于给定值 val 的所有节点(2)反转一个单链表(3) 合并两个有序链表(4)链表的中间结点(5)链表中…...
树_二叉搜索树累加求和
//给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 // node.val 的值之和。 // // 提醒一下,二叉搜索树满足下列约束…...
gcc编译流程概述
前言 本篇文章介绍gcc编译器编译C文件的流程概述 比如我们创建了一个.c文件hello_gcc.c #include <stdio.h> int main() {printf("Hello gcc!!!\n");return 0; }最简单的方式就是在终端使用命令 gcc hello_gcc.c -o hello_gcc // 编译、汇编、链接 ./hello_…...
【web安全】ssrf漏洞的原理与使用
前言 菜某对ssrf漏洞的总结。 ssrf的作用 主要作用:访问外界无法访问的内网进行信息收集。 1.进行端口扫描,资源访问 2.指纹信息识别,访问相应的默认文件 3.利用漏洞或者和payload进一步运行其他程序 4.get类型漏洞利用,传参数…...
佳易王会员管理软件店铺积分以及积分兑换系统
一、佳易王会员管理软件大众版 部分功能简介: 1、会员信息登记 :可以直接使用手机号登记,也可以使用实体卡片,推荐用手机号即可。 2、会员卡类型 :可以自由设置卡的类型,比如:充值卡、计次卡、…...
Django回顾【二】
目录 一、Web框架 二、WSGI协议 三、 Django框架 1、MVC与MTV模型 2、Django的下载与使用 补充 3、启动django项目 补充 5、 Django请求生命周期 四、路由控制 1、路由是什么? 2、如何使用 3、path详细使用 4、re_path详细使用 5、反向解析 6、路由…...
[Ubuntu 18.04] RK3399搭建SSH服务实现远程访问
SSH(Secure Shell)是一种网络协议和软件,用于安全地远程登录到计算机并进行网络服务的加密通信。它提供了加密的认证和安全的数据传输,使得在不安全的网络中进行远程管理和访问变得更加安全。 以下是 SSH 服务的一些关键特点和用途: 安全认证:SSH 使用公钥/私钥加密技术…...
Linux进程间通信之共享内存
📟作者主页:慢热的陕西人 🌴专栏链接:Linux 📣欢迎各位大佬👍点赞🔥关注🚓收藏,🍉留言 本博客主要内容讲解共享内存原理和相关接口的介绍,以及一个…...
lv11 嵌入式开发 RTC 17
目录 1 RTC简介 编辑2 Exynos4412下的RTC控制器 2.1 概述 2.2 特征 2.3 功能框图 3 寄存器介绍 3.1 概述 3.2 BCD格式的年月日寄存器 3.3 INTP中断挂起寄存器 3.4 RTCCON控制寄存器 3.5 CURTICCNT 作为嘀嗒定时器使用的寄存器 4 RTC编程 5 练习 1 RTC简介 RTC(…...
c语言指针详解(上)
目录 一、指针的基本概念和用法 二、指针运算 2.1 指针的自增和自减运算 2.2 指针的自增和自减运算 三、数组和指针 四、指针和函数 4.1 在函数中使用指针作为参数和返回值 4.1.1 使用指针作为函数参数 4.1.2 使用指针作为函数返回值 4.2 指针参数的传值和传引用特性 4.2.1 指针…...
如何删除mac苹果电脑上面的流氓软件?
在使用苹果电脑的过程中,有时候我们也会遇到一些不需要的软件。无论是因为不再需要,或者是为了释放磁盘空间,删除这些软件是很重要的。本文将为大家介绍怎样删除苹果电脑上的软件! CleanMyMac X全新版下载如下: https://wm.make…...
WordPress(11)给文章添加预计阅读时长
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、文件配置二、代码块1.引入库2.配置 single.php三、效果图前言 提示:这里可以添加本文要记录的大概内容: 例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了…...
周周爱学习之快速排序
快速排序,顾名思义,快速排序是一种速度非常快的一种排序算法 平均时间复杂度为O(),最坏时间复杂度为O()数据量较大时,优势非常明显属于不稳定排序 1.算法描述 每一轮排序选择一个基准点(pivot)进行分区 让小于基准点…...
国产接口测试工具APIpost
说实话,了解APIpost是因为,我的所有接口相关的文章下,都有该APIpost水军的评论,无非就是APIpost是中文版的postman,有多么多么好用,虽然咱也还不是什么啥网红,但是不知会一声就乱在评论区打广告…...
MySQL电商管理系统练习题及答案
一 、表结构 用户表(user):id(主键)、username、password、email、phone、age商品表(product):id(主键)、name、price、stock、description订单表(order):id(主键)、user_id(外键,关联用户表)、total_price、status、create_time…...
每日3道PWN(第二天)
ciscn_2019_n_1 参考: [BUUCTF-pwn]——ciscn_2019_n_1-CSDN博客 [BUUCTF]PWN5——ciscn_2019_n_1_ciscn_2019_n_4-CSDN博客 BUUCTF—ciscn_2019_n_1 1-CSDN博客 checksec一下 64位栈溢出 按f5查看main函数,双击可疑函数 发现含有命令执行的且发现fl…...
SAP STMS传输请求
一、概述 一般SAP项目上都会有六套系统,分别是: 测试环境-DEV系统 主要由100:沙盘系统:用于业务顾问配置 200:开发系统:用于开发ABAP写代码 300:测试系统:主要是单元测试、顾问自己…...
L1-009:N个数求和
目录 ⭐题目描述⭐ ⭐分析 ⭐程序代码 运行结果 ⭐文案分享⭐ ⭐题目描述⭐ 本题的要求很简单,就是求N个数字的和。麻烦的是,这些数字是以有理数分子/分母的形式给出的,你输出的和也必须是有理数的形式。 输入格式: 输入第一行给出…...
当发送“Hello,World”时,channel发生了什么?
一、Netty概述 1.Netty是什么? Netty 是一个异步的、基于事件驱动的网络应用框架,用于快速开发可维护、高性能的网络服务器和客户端。 2.Netty的地位怎么样? Netty 在 Java 网络应用框架中的地位就好比:Spring 框架在 JavaEE …...
服务器运行情况及线上排查问题常用命令
一、top命令 指令行: top返回: 返回分为两部分 (一)系统概览,见图知意 以下是几个需要注意的参数 1、load average: 系统负载,即任务队列的平均长度。三个数值分别为 1分钟、5分钟、15分…...
Hadoop学习笔记(HDP)-Part.18 安装Flink
目录 Part.01 关于HDP Part.02 核心组件原理 Part.03 资源规划 Part.04 基础环境配置 Part.05 Yum源配置 Part.06 安装OracleJDK Part.07 安装MySQL Part.08 部署Ambari集群 Part.09 安装OpenLDAP Part.10 创建集群 Part.11 安装Kerberos Part.12 安装HDFS Part.13 安装Ranger …...
LeetCode56. 合并区间
🔗:【贪心算法,合并区间有细节!LeetCode:56.合并区间-哔哩哔哩】 class Solution { public:vector<vector<int>> merge(vector<vector<int>>& intervals) {if(intervals.size()0){return intervals;…...
解决typescript报错:找不到名称xxx
现象: 原因:在同时导入默认导出和命名导出时,默认导出必须放在命名导出之前 下面的就是原始文件: 默认导出指: export default导出类型, import时无需大括号 命名导出指: 仅有export关键字…...
UVM中封装成agent
在验证平台中加入monitor时,看到driver和monitor之间的联系:两者之间的代码高度相似。其本质是因为二者 处理的是同一种协议,在同样一套既定的规则下做着不同的事情。由于二者的这种相似性,UVM中通常将二者封装在一起,…...
OSI七层模型与TCP/IP四层模型
一、OSI七层模型简述 OSI 模型的七层是什么?在 OSI 模型中如何进行通信?OSI 模型有哪些替代方案? TCP/IP 模型关于专有协议和模型的说明 二、七层模型详解(DNS、CDN、OSI) 状态码DNS nslookup命令 CDN whois命令 …...
QT 中 QProgressDialog 进度条窗口 备查
基础API //两个构造函数 QProgressDialog::QProgressDialog(QWidget *parent nullptr, Qt::WindowFlags f Qt::WindowFlags());QProgressDialog::QProgressDialog(const QString &labelText, const QString &cancelButtonText, int minimum, int maximum, QWidget *…...
学习ShardingSphere前置知识
学习ShardingSphere前置准备知识 一. SPI SPI(Service Provider Interface)是一种Java的扩展机制,用于实现组件之间的松耦合。在SPI模型中,服务提供者(Service Provider)定义了一组接口,而服务…...
读书笔记-《数据结构与算法》-摘要3[选择排序]
选择排序 核心:不断地选择剩余元素中的最小者。 找到数组中最小元素并将其和数组第一个元素交换位置。在剩下的元素中找到最小元素并将其与数组第二个元素交换,直至整个数组排序。 性质: 比较次数(N-1)(N-2)(N-3)…21~N^2/2交换次数N运行…...
Arduino驱动MLX90614红外测温传感器(温湿度传感器)
目录 1、传感器特性 2、测量方法 3、硬件原理图 4、控制器和传感器连线图...
Ubuntu上传文件到SMB共享文件夹
0. 前言 公司有一些数据共享文件夹,平时可以把开发的重要文件放到上面备份。本人开发使用ubuntu系统,共享文件夹是windows的形式,想通过命令的方式,方便快捷,还可shell脚本自动化。 1. 安装挂载库 sudo apt-get upd…...
培训页面设计师/西安seo外包行者seo06
Oracle读取和修改数据块的过程Oracle数据库处理SQL都会经过三个过程:解析(parse)、执行(exec)、返回结果(fetch)。为了便于理解,我们首先省略的SQL的处理过程,而直接介绍数据块的读取或修改过程。物理读和逻辑读概念1.对要访问的块地址做HASHHASH(FILE#,…...
wordpress 分类目录/怎么优化自己网站
版本过高错误 比如我的webpack是3.6.0版本 而我的css-loader是5.0.0 这里就会出现这个错误 解决办法: 1,手动设置,然后采用npm install 重新下载 2,卸载重装 npm uninstall css-loader //卸载 npm install css-loader3.0.0 --s…...
网站在建设中是什么意思/交换链接的其它叫法是
1、Ext2文件系统规划(参照《鸟哥Linux私房菜基础篇》)磁盘分区后进行格式化,这时文件系统会将inode与block规划好,除非再次进行格式化,否则不会改变。但是如今的文件系统很大,有的高达几百G,这样会是的inode与block的数…...
独立站怎么推广/百度页面
本文作者陈恒捷是TesterHome社区主编,第十届MTSC大会上海站-开源专场出品人。先后在PP助手、PPmoney、荔枝等公司从事测试效能提升相关工作,在测试技术及效率提升方面有丰富的经验积累。 背景 流量录制回放近几年已经越来越火。如阿里开放的 doom 、滴滴…...
网站全站优化/公司推广策划
作者 | JiekeXu来源 | JiekeXu之路(ID: JiekeXu_IT)转载请联系授权 | (微信ID:xxq1426321293)大家好,我是 JiekeXu,很高兴又和大家见面了,今天分享下 Oracle 19c 之多租户 PDB 连接与访问。本文首发于微信公众号【Jiek…...
拍网制作方法图片教程/佛山旺道seo
在我的周边朋友身边就发生过这样的事情: 故事1:A君在北京从事Java开发好多年了,萌发了创业的念头,想组建了一个开发团队想大干一场。但是慢慢发现,构建一个有战斗力的团队真不容易。后来技术团队的组建初步有了起色&am…...