目录

数组&链表基础

高频面试题(leetcode)

206 反转链表(常考)

方法1:迭代算法(双指针)(cpp&python)

方法2:递归解法

妖魔化的双指针算法。

24 两两交换链表中的节点

拓展:哑节点

141环形链表

方法1:快慢指针算法。

方法2:哈希表

142 环形链表2

扩展:哈希表基础及其在c++和python中的基本语法。

set和unordered_set区别以及适用情况

致谢


数组&链表基础

数组定义:

数组是一个固定长度的存储相同数据类型的数据结构,数组中的元素被存储在一段连续的内存空间中。它是最简单的数据结构之一,大多数现代编程语言都内置数组支持。

数组在遍历时速度非常快,但是在删除和增加元素时需要平移大量的元素(删除和增加首末位置除外),复杂度为o(n)。

数组特点:

  1. 使用前需要申请数组长度,声明长度之后不能更改;
  2. 插入和删除操作需要移动大量的元素,效率比较慢;
  3. 只能存储一种类型的数据;

链表定义:

链表是一种物理存储单元上非联系、非顺序的存储结构。数据元素中的逻辑顺序是通过链表中的指针连接次序依次实现的,链表由一系列的节点(链表中每一个元素称为节点)组成,节点可以在运行时动态生成,节点的数据空间一般会包含一个数据域和一个指针域,该指针一般称为next,用来指向下一个节点的位置。

链表特点:

  1. 节点之间通过指针相连;
  2. 每个节点有一个前驱节点和一个后继节点;
  3. 首节点没有前驱节点,尾节点没有后继节点;
  4. n个节点离散分配;

链表图解

链表分类:

单向链表:

链表中的元素只能指向链表中的下一个元素,元素之间不能互相指向。

双向链表:

每个链表既有指向下一个元素的指针,又有指向上一个元素的指针,每个节点都有两个指针。

循环链表:

高频面试题(leetcode)

206 反转链表(常考)

206. 反转链表 - 力扣(LeetCode) (leetcode-cn.com)https://leetcode-cn.com/problems/reverse-linked-list/

方法1:迭代算法(双指针)(cpp&python)

  • 定义curr,pre指针,curr指针初始化为head,pre指针为空指针;
  • 定义tmp指针,存储curr的下一节点;
  • curr的next指针指向pre;
  • curr和pre均向前移动一个位置;
/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode() : val(0), next(nullptr) {}*     ListNode(int x) : val(x), next(nullptr) {}*     ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution {
public:ListNode* reverseList(ListNode* head) {ListNode*curr = head,*pre = nullptr;    //定义两个指针while(cur){ListNode* tmp = cur->next;    // 存储当前的下一个节点数据curr->next = pre;    //cur下一节点 指向prepre = curr;    //pre指针前进一位curr = tmp;    // cur指针前进一位}return pre;        }
};
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:def reverseList(self, head: ListNode) -> ListNode:cur,pre = head,Nonewhile cur:# 同时赋值,省掉tmpcur.next,pre,cur = pre,cur,cur.nextreturn pre

方法2:递归解法

双指针的办法是调换相邻的两个节点,递归是找到链表的最后一个节点,从尾到首依次反转。

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode() : val(0), next(nullptr) {}*     ListNode(int x) : val(x), next(nullptr) {}*     ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution {
public:ListNode* reverseList(ListNode* head) {if (head == 0 || head->next == 0) return head;ListNode* tmp = reverseList(head->next);head->next->next = head;head->next = nullptr;return tmp;}
};
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:def reverseList(self, head: ListNode) -> ListNode:
#        if head is None or head.next is None:return head   # 这个也行if not head or not head.next:return headtmp = self.reverseList(head.next)head.next.next = headhead.next = Nonereturn tmp

妖魔化的双指针算法。

  • 定义指针curr,初始化为head;
  • 将head的下一个节点的next指向curr,实现局部反转;
  • 局部反转完成之后,curr和head的next指针同时向前移动一个位置;
  • 循环,一直到curr达到链表的最后一个节点;
/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode() : val(0), next(nullptr) {}*     ListNode(int x) : val(x), next(nullptr) {}*     ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution {
public:ListNode* reverseList(ListNode* head) {if (head == nullptr) { return nullptr;}ListNode* curr = head;while (head->next){ListNode* tmp = head->next->next;head->next->next= curr;curr = head->next;head->next = tmp;}return curr;   }
};
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:def reverseList(self, head: ListNode) -> ListNode:if head == None:return Nonecurr = headwhile (head.next):tmp = head.next.nexthead.next.next = currcurr = head.nexthead.next = tmpreturn curr

24 两两交换链表中的节点

迭代算法,创建哑节点。

  • 创建哑结点,令dummyHead.next = head;tmp表示当前到达的节点,初始化为dummyHead;每次交换tmp后面的两个节点。
  • tmp后面的节点分别为node1和node2,交换之前:tmp->node1->node2,交换之后:tmp->node2->node1;
  • 迭代,当新的链表的头节点为dummyHead.next,停止迭代。

示意图:

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode() : val(0), next(nullptr) {}*     ListNode(int x) : val(x), next(nullptr) {}*     ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution {
public:ListNode* swapPairs(ListNode* head) {ListNode* dummyHead = new ListNode(0);dummyHead->next = head;ListNode* tmp = dummyHead;while  (tmp->next != nullptr && tmp->next->next != nullptr){ListNode* node1 = tmp->next;ListNode* node2 = tmp->next->next;tmp->next = node2;node1->next = node2->next;node2->next = node1;tmp = node1;           }return dummyHead->next;}
};
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:def swapPairs(self, head: ListNode) -> ListNode:dummyHead = ListNode(0)dummyHead.next = headtmp = dummyHeadwhile (tmp.next and tmp.next.next):node1 = tmp.nextnode2 = tmp.next.nexttmp.next = node2node1.next = node2.nextnode2.next = node1tmp = node1return dummyHead.next

拓展:哑节点

哑节点是在处理与链表相关的操作时,设置在链表头之前的指向链表头的节点,用于简化与链表头相关的操作。因为LeetCode上的题的测试用例都是在头结点就已经存储数据,所以我们需要一个哑结点,放在头结点的前面。

ListNode dummy = new ListNode(0);
dummy.next = head;
//head是链表的头节点,dummy就是指向链表头部的哑节点。

具体可以参考:

(15条消息) 链表 - 哑节点_Hi-YOLO的博客-CSDN博客_哑节点

141环形链表

141. 环形链表 - 力扣(LeetCode) (leetcode-cn.com)https://leetcode-cn.com/problems/linked-list-cycle/

方法1:快慢指针算法。

我们定义两个指针,一快一满。慢指针每次只移动一步,而快指针每次移动两步。初始时,慢指针在位置 head,而快指针在位置 head.next。这样一来,如果在移动的过程中,快指针反过来追上慢指针,就说明该链表为环形链表。否则快指针将到达链表尾部,该链表不为环形链表。

步骤示意图:

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode(int x) : val(x), next(NULL) {}* };*/
class Solution {
public:bool hasCycle(ListNode *head) {if (head == nullptr || head->next == nullptr){ return false;}ListNode* fast = head->next;ListNode* slow = head;while (fast != slow){if (fast == nullptr || fast->next == nullptr){ return false;}fast = fast->next->next;slow = slow->next;}return true;       }
};
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = Noneclass Solution:def hasCycle(self, head: Optional[ListNode]) -> bool:if(head == None or head.next == None):return Falsefast = head.nextslow = headwhile (fast != slow):if (fast == None or fast.next == None):return Falsefast = fast.next.nextslow = slow.nextreturn True

写一个python简洁版本:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = Noneclass Solution:def hasCycle(self, head: Optional[ListNode]) -> bool:fast = slow = headwhile slow and fast and fast.next.next:slow = slow.nextfast = fast.next.nextif slow is fast:return Truereturn False

方法2:哈希表

哈希表来存储所有已经访问过的节点。每次我们到达一个节点,如果该节点已经存在于哈希表中,则说明该链表是环形链表,否则就将该节点加入哈希表中。重复这一过程,直到我们遍历完整个链表即可。

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode(int x) : val(x), next(NULL) {}* };*/
class Solution {
public:bool hasCycle(ListNode *head) {unordered_set<ListNode*> seen;while (head != nullptr){if (seen.count(head)){return true;}seen.insert(head);head = head->next;}return false;}
};
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = Noneclass Solution:def hasCycle(self, head: Optional[ListNode]) -> bool:if (head == None or head.next == None):return Falseseen = set()while (head):if head in seen:return Trueseen.add(head)head = head.nextreturn False

142 环形链表2

142. 环形链表 II - 力扣(LeetCode) (leetcode-cn.com)https://leetcode-cn.com/problems/linked-list-cycle-ii/

方法1:哈希表

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode(int x) : val(x), next(NULL) {}* };*/
class Solution {
public:ListNode *detectCycle(ListNode *head) {unordered_set<ListNode*> visit;if (head == nullptr || head->next == nullptr){return nullptr;}while (head != nullptr){if (visit.count(head)){return head;}visit.insert(head);head = head->next;}return nullptr;}
};
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = Noneclass Solution:def detectCycle(self, head: ListNode) -> ListNode:visit = set()if not head or not head.next:return Nonewhile (head):if head in visit:return headvisit.add(head)head = head.nextreturn None

 注:暂时不明白

扩展:哈希表基础及其在c++和python中的基本语法。

set集合

官方文档:

内置类型 — Python 3.10.3 文档https://docs.python.org/zh-cn/3/library/stdtypes.html?highlight=set#set

[unordered_map - C++ Referencehttp://[unordered_map - C++ Reference (cplusplus.com)](http://www.cplusplus.com/reference/unordered_map/unordered_map/?kw=unordered_map)

集合是按照特定顺序存储唯一元素的容器。

在集合中,元素的值也标识它(值本身就是键,类型为 T),并且每个值必须是唯一的。

集合中元素的值不能在容器中修改一次(元素始终为 const),但可以从容器中插入或删除它们。 在内部,集合中的元素始终按照其内部比较对象(比较类型)指示的特定严格弱排序标准进行排序。

set 容器通常比 unordered_set 容器通过键访问单个元素要慢,但它们允许根据它们的顺序对子集进行直接迭代。

集合通常实现为二叉搜索树。

基本函数(c++):

  1. begin()--返回指向第一个元素的迭代器
  2. clear()--清除所有元素
  3. count()--返回某个值元素的个数//值为1或者0
  4. empty()--如果集合为空,返回true
  5. end()--返回指向最后一个元素的迭代器
  6. equal_range()--返回集合中与给定值相等的上下限的两个迭代器
  7. erase()--删除集合中的元素
  8. find()--返回一个指向被查找到元素的迭代器
  9. get_allocator()--返回集合的分配器
  10. insert()--在集合中插入元素
  11. lower_bound()--返回指向大于(或等于)某值的第一个元素的迭代器
  12. key_comp()--返回一个用于元素间值比较的函数
  13. max_size()--返回集合能容纳的元素的最大限值
  14. rbegin()--返回指向集合中最后一个元素的反向迭代器
  15. rend()--返回指向集合中第一个元素的反向迭代器
  16. size()--集合中元素的数目
  17. swap()--交换两个集合变量
  18. upper_bound()--返回大于某个值元素的迭代器
  19. value_comp()--返回一个用于比较元素间的值的函数1.

多看c++官方文档:

set - C++ Reference (cplusplus.com)

基本函数(python)

 多看官方文档:

内置类型 — Python 3.10.2 文档

set和unordered_set区别以及适用情况

(17条消息) set和unordered_set区别以及适用情况_小乾的计算机学习之路-CSDN博客_set unordered_set

致谢

【反转链表】:双指针,递归,妖魔化的双指针 - 反转链表 - 力扣(LeetCode) (leetcode-cn.com)(15条消息) 链表 - 哑节点_Hi-YOLO的博客-CSDN博客_哑节点

(17条消息) Python集合(set)的操作及方法_小七的博客-CSDN博客_python set

(22条消息) 链表(图文详解)_糊涂糖僧的博客-CSDN博客_链表

【数据结构与算法】03 链表(基础知识+面试高频leetcode题目)相关推荐

  1. 【超全汇总】学习数据结构与算法,计算机基础知识,看这篇就够了【ZT帅地】2020-3-7

    https://blog.csdn.net/m0_37907797/article/details/104029002 由于文章有点多,并且发的文章也不是一个系列一个系列发的,不过我的文章大部分都是围 ...

  2. 计算机基础知识数据结构与算法,(计算机基础知识)[数据结构与算法] 图

    第六章 图 6.1 图的定义和基本术语 图: G=(V,E) Graph = (Vertex, Edge) V: 顶点(数据元素)的有穷非空集合 E: 边的有穷集合 完全图: 任意两个点都有一条边相连 ...

  3. Interview之AI:人工智能领域岗位求职面试—人工智能算法工程师知识框架及课程大纲(AI基础之数学基础/数据结构与算法/编程学习基础、ML算法简介、DL算法简介)来理解技术交互流程

    Interview之AI:人工智能领域岗位求职面试-人工智能算法工程师知识框架及课程大纲(AI基础之数学基础/数据结构与算法/编程学习基础.ML算法简介.DL算法简介)来理解技术交互流程 目录 一.A ...

  4. 一文通数据结构与算法之——链表+常见题型与解题策略+Leetcode经典题

    文章目录 1 链表 1.1 常见题型及解题策略 1.1.1 LeetCode中关于链表的题目有以下五种类型题: 1.1.2 解题策略 1.2 链表的基本内容 1.2.1 链表的基本结构: 1.2.2 ...

  5. 数据结构与算法 内核链表实现商品购物系统项目+Makefile

    数据结构与算法 内核链表实现商品购物系统项目 第一章 项目实现思维 [1]编译介绍 [2]框架思维 第二章 Makefile编写 第三章 代码编写实现 [1]favorite.txt文件 [2]his ...

  6. python定义链表节点_Python数据结构与算法之链表定义与用法实例详解【单链表、循环链表】...

    本文实例讲述了Python数据结构与算法之链表定义与用法.分享给大家供大家参考,具体如下: 本文将为大家讲解: (1)从链表节点的定义开始,以类的方式,面向对象的思想进行链表的设计 (2)链表类插入和 ...

  7. mysql系列问答题_(2)MySQL运维基础知识面试问答题

    面试题001:请解释关系型数据库概念及主要特点? 面试题002:请说出关系型数据库的典型产品.特点及应用场景? 面试题003:请解释非关系型数据库概念及主要特点? 面试题004:请说出非关系型数据库的 ...

  8. 数据结构与算法之链表结构寻找p、q最近的公共祖先

    链表结构,寻找p.q最近的公共祖先 数据结构与算法之链表结构寻找p.q最近的公共祖先 链表结构,寻找p.q最近的公共祖先 问题 想法 代码 问题 设一棵二叉树的结点结构为(LLINK, INFO, R ...

  9. 数据结构与算法--单链表相关面试题

    此文章仅作为自己学习过程中的记录和总结,同时会有意地去用英文来做笔记,一些术语的英译不太准确,内容如有错漏也请多指教,谢谢! 一.概述 获取单链表的有效元素个数[新浪面试题1] 获取单链表倒数第k个结 ...

最新文章

  1. 用 Flask 来写个轻博客 (14) — M(V)C_实现项目首页的模板
  2. 面试总结-腾讯产品群面
  3. 过程化技术:打造「开放世界」的秘密
  4. Android 自定义ViewGroup
  5. Pycharm配置运行/调试时的工作目录
  6. JAVA学生宿舍管理系统
  7. 7、乐趣国学—趣谈“圣贤”
  8. MATLAB绘图:导出矢量图
  9. python自带的库有哪些_python自带库
  10. 蓝光手游大师极速版 V1.0.82
  11. jqgrid 加载mysql数据_利用jqgrid+加mysql的text类型实现简单自定义数据模型
  12. Win10部分引起鼠标卡顿间歇性失灵的原因
  13. 云洲智能,能否成为科创板无人船艇第一股?
  14. js中类似`${xx,xxxy}`的语句
  15. 国标28181:什么是SIP协议
  16. vue中DatePicker从前台到后台日期偶尔差一天
  17. mybatis if-else(chose when otherwise )
  18. 未能检测服务器连接失败,被控链接失败处理检查方法
  19. mysql2008百度云_SQLServer数据库之SQL Server 2008R2 企业版 百度云下载地址
  20. CLIPCAP:图生文

热门文章

  1. conda的安装与使用
  2. 在之后10个月里要践行的学习方法
  3. 深入剖析实战Spring
  4. 利用SQL创建表结构
  5. Python - 两数相除 递进版
  6. 第三方支付公司充值、提现、转账流程
  7. Oracle中的NVL函数、NVL2函数和NULLIF函数
  8. Cohort Analysis:留存分析Excel版
  9. linux环境掌握熟悉一下,熟悉linux环境
  10. BMP24位照片格式