链表是最常见的数据结构之一,下面主要总结题目,不涉及基本的数据结构的介绍
文章目录
-
- 1. 常见的链表操作题目
- 2. leetcode 其他相关题目
-
- No.2 Add Two Numbers(两数相加)
- No.24 Swap Nodes in Pairs(两两交换链表中的节点)
- No.82 Remove Duplicates from Sorted List II(删除排序链表中的重复元素Ⅱ)
- No.83 Remove Duplicates from Sorted List(删除排序链表中的重复元素)
- No.86 Partition List(分隔链表)
- No.92 Reverse Linked List II(倒置链表Ⅱ)
- No.160 Intersection of Two Linked Lists(相交链表)
- No.203 Remove Linked List Elements(移除链表元素)
- No.234 Palindrome Linked List(回文链表)
- No.237 Delete Node in a Linked List (删除链表中的节点)
- No.328 Odd Even Linked List(奇偶链表)
- No.445 Add Two Numbers II(两数相加Ⅱ)
- No.817 Linked List Components(链表组件)
- 3. 解链表题的一些心得
1. 常见的链表操作题目
1.1 删除链表倒数第 n 个结点(leetcode 19)
只遍历一次,保证输入的 n 是有效的,问如何删除倒数第 n 个结点
// 思路:一快一慢两个节点进行遍历,快的结点比慢的结点先走 n 步
public ListNode removeNthFromEnd(ListNode head, int n) {
// 设置哨兵结点,处理涉及头结点的情况
ListNode start = new ListNode(0);
ListNode slow = start, fast = start;
slow.next = head;
// 快结点提前走 n + 1 步(包含了头结点)
for (int i = 0; i <= n; i++) {
fast = fast.next;
}
// 找出倒数第 n 个结点
while (fast != null) {
slow = slow.next;
fast = fast.next;
}
slow.next = slow.next.next;
return start.next;
}
1.2 两个有序链表的合并(leetcode 21)
确定初始节点,之后两条链表一边遍历一边比较跟赋值,直到一条链遍历完,将另一条链剩余的部分接在输出的链尾上
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
// 快速返回,如果有一边为空,则合并结果为另外一个队列
if (l1 == null) {
return l2;
}
if (l2 == null) {
return l1;
}
ListNode head = new ListNode(0);
ListNode temp = head;
// 遍历,直到有一个队列被遍历完
while (l1 != null && l2 != null) {
if(l1.val < l2.val) {
temp.next = l1;
l1 = l1.next;
} else {
temp.next = l2;
l2 = l2.next;
}
temp = temp.next;
temp.next = null;
}
// 将另外一个未被遍历完的队列,接在合并队列的后面
if (l1 == null) {
temp.next = l2;
}
if (l2 == null) {
temp.next = l1;
}
return head.next;
}
1.3 链表中环的检测(leetcode 141)
Given a linked list, determine if it has a cycle in it.
Follow up:
Can you solve it without using extra space?
// 用一快一慢两个结点进行遍历,快结点一次遍历两个结点,慢结点一次遍历一个结点
// 如果有环存在的话,快结点无法遍历到链表的末尾,最终会与慢结点相遇
public boolean hasCycle(ListNode head) {
if (head == null) {
return false;
}
ListNode fast = head;
ListNode slow = head;
while (fast.next != null && fast.next.next != null) {
fast = fast.next.next;
slow = slow.next;
if (fast == slow) {
return true;
}
}
return false;
}
1.4 链表倒置(leetcode 206)
思路:先考虑如何改变链表中部的指向问题,之后考虑开头跟结尾的特殊情况
public ListNode reverseList(ListNode head) {
ListNode pre = null;
ListNode cur = head;
ListNode next = head;
while (next != null) {
next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
return pre;
}
1.5 链表的中间结点(leetcode 876)
Given a non-empty, singly linked list with head node head, return a middle node of linked list.
If there are two middle nodes, return the second middle node.
public ListNode middleNode(ListNode head) {
ListNode a = head;
ListNode b = head;
while (a != null && a.next != null) {
a = a.next.next;
b = b.next;
}
return b;
}
2. leetcode 其他相关题目
代码 github 链接:https://github.com/Parallelline1996/-Algorithm/tree/master/Leetcode/src
No.2 Add Two Numbers(两数相加)
You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
You may assume the two numbers do not contain any leading zero, except the number 0 itself.
- Example:
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
Explanation: 342 + 465 = 807.
/*
思路:注意这里不能将两个数读出来再相加,因为涉及一个Integer类型,Long类型有最大值的问题
注意这里链表是将数字进行倒置,所以刚好两个链表从头到尾遍历,就是两个数从末一位
分别相加到最高位的过程,这里要注意相加过程中的进位问题。
*/
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode output = null;
ListNode head = null;
int a, b, add = 0, total;
while (l1 != null || l2 != null) {
if (l1 != null) {
a = l1.va