LeetCode链表
Ban
ChangAn University链表
链表基础
206 链表逆序(Easy)
LeetCode 206. Reverse Linked List
Easy
已知链表头节点指针head,将链表逆序(不可申请额外空间)
1 -> 2 -> 3 -> 4 -> 5 -> NULL 5 -> 4 -> 3 -> 2 -> 1 -> NULL
- JAVA
92 链表逆序2(Medium)
92.反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。
说明: 1 ≤ m ≤ n ≤ 链表长度。
示例:
输入: 1->2->3->4->5->NULL, m = 2, n = 4 输出: 1->4->3->2->5->NULL
- 思路
关节节点
- 逆置端头节点的前驱-> 红色节点 原本红色指向蓝色,现在红色指向绿色(红->绿)
- 逆置前头节点->蓝色节点 逆置前的开始节点 -> 逆置后的尾节点, 逆置后尾节点指向逆置端尾节点后继(蓝->橙)
- 逆置前的尾节点->绿色节点 逆置后的头节点,需要让逆置段头节点的前驱指向逆置后的头节点(红->绿)
- 逆置段尾节点的后继 -> 橙色节点 逆置后,蓝色节点指向橙色节点(蓝->橙)
步骤
- 找到逆置段头节点的前驱(红)和逆置前头节点(逆置后尾节点)(蓝) head指针向前移动m-1个位置,就找到了逆置前头节点 pre_head:记录head指针的前驱节点 将逆置前头节点(蓝色)的地址存入临时变量modify_list_tail,用来操作逆置后的尾节点,让它指向逆置段尾节点的后继(橙色)
- 逆置n-m+1个节点,记为逆置长度change_len,用简单逆置代码实现
- 各节点相连,将逆置前头节点前驱pre_head和逆置后的头节点new_head相连,modify_list_tail与head相连
思考
最终结果应该返回哪一个节点?
将最开始的head节点记为结果节点
如果m=1,需要考虑什么特殊情况? 从第一个元素开始逆置 -> pre_head_pointer为NULL -> 结果为逆置前的尾节点,逆置后的头节点new_head_pointer
cpp
- java
160 两个链表的交点(Easy)
LeetCode 160
法1 使用set
/*要求1.如果两个链表没有交点,返回null2.在求交点的过程中,不可破坏链表的结构或修改链表数据域3.可以确保传入的链表A和链表B没有任何环4.实现算法尽可能使时间复杂度O(n)空间复杂度O(1)方法1 set法1.遍历链表A,将A中节点对应指针插入set2.遍历链表B,将B中节点对应地址指针在set中查找发现set中的第一个节点地址,即两个链表的交点*/struct ListNode {int val;ListNode *next;ListNode(int x) : val(x), next(NULL) {}};class Solution {public:ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {set<ListNode*> node_set;while (headA) {node_set.insert(headA);headA = headA->next;}while (headB) {if (node_set.find(headB) != node_set.end()) {return headB;}headB = headB->next;}return NULL;}};class Solution {public ListNode getIntersectionNode(ListNode headA, ListNode headB) {List<ListNode> nodeList = new ArrayList<ListNode>();while (headA != null) {nodeList.add(headA);headA = headA.next;}while (headB != null) {if (nodeList.contains(headB)) {return headB;}headB = headB.next;}return null;}}class Solve {public static void main(String[] args) {ListNode a = new ListNode(2);ListNode b = new ListNode(3);a.next = b;ListNode result = new Solution().getIntersectionNode(a, b);System.out.println(result);}}
- 法2 - 数学计算法, 空间复杂度O(1)
142 链表求环(Medium)
LeetCode 142
已知链表中可能存在环,若有环返回环起始节点,否则返回NULL
- 法一,使用Set
- 法2 ,快慢指针赛跑法(经典思想)
由于链表存在环,则快指针会将慢指针套圈; 如果链表不存在环,则块指针无法套环慢指针
- 快指针:每次遍历走两步
- 慢指针:每次遍历走一步
套环则存在环->可解141题 -> 但142题要求返回环起点
如何求出环起点?
86 链表划分(Medium)
Leecode 86 已知链表头指针head与数值x,将所有小于x的节点放在大于或等于x的节点前,且保持这些节点的原来的相对位置
设置两个临时节点:
- less_head: 只要遇到小于x的节点,就用less_ptr将其插入less_head
- more_head: 同理,大于x就用more_ptr插入more_head
- 最后将less_ptr指向域设置为more_head的下一个节点, more_ptr的指向域设置为NULL
- 返回less_head的next域指向的节点
138 复制带随机指针的链表(hard)
LeetCode 138 Copy List With Random Pointer
A linked list is given such that each node contains an additional random pointer which could point to any node in the list or NULL
Return a deep copy of the list
The Linked list is represented in the input/output as a list o n
codes. Each node is represented as a pair of [val, random_index]
where:
val
: an integer representingNode.val
random_index
: the index of the node(range from0
ton-1
) where random pointer points to, orNULL
if it does not point to any node
什么是深拷贝:构造生成一个全新的链表,即使将原链表毁坏,新链表可独立使用
难点:如何拷贝原链表的随机指针到新链表,如何构建新链表中的随机指针。 将原链表的随机指针逻辑关系,生成在新链表中
法1: map
思路:使用Map
map实例:
思路: 节点地址与节点序号对应
难点: (第几个指的是位置)
- 原链表某节点的random指针指向了第几个节点
- 新链表任意某个节点,对应为第几个节点
法2 空间迭代法(官方题解 法3)
思路查看官方题解 , 官方题解
21 合并两个排序链表(Easy)
- Merge Two Sorted Lists
Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists
23 合并多个排序链表(Hard)
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
- 法2实现,排列法
- 法3,分治法
162分钟
建议
完全自主重新编写题目解答
尽量多的通过这些题目
重新编写一边题目并提交
在纸上写代码,反复练习
完成其他leetcode链表题目