链表专题
文章目录
- 链表专题
-
-
- [21. 合并两个有序链表](#21. 合并两个有序链表)
- [2. 两数相加](#2. 两数相加)
- [19. 删除链表的倒数第 N 个结点](#19. 删除链表的倒数第 N 个结点)
- [24. 两两交换链表中的节点](#24. 两两交换链表中的节点)
- 92.反转链表II
- [25. K 个一组翻转链表](#25. K 个一组翻转链表)
-
21. 合并两个有序链表
java
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
ListNode dummy = new ListNode();
ListNode cur = dummy; // cur 指向新链表的末尾
while (list1 != null && list2 != null) {
if (list1.val < list2.val) {
cur.next = list1; // 把 list1 加到新链表中
list1 = list1.next;
} else { // 注:相等的情况加哪个节点都是可以的
cur.next = list2; // 把 list2 加到新链表中
list2 = list2.next;
}
cur = cur.next;
}
cur.next = list1 != null ? list1 : list2; // 拼接剩余链表
return dummy.next;
}
}
2. 两数相加
java
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode head = null,tail = null;
int carry = 0;
while(l1 != null || l2 != null){
int n1 = l1 != null ? l1.val : 0;
int n2 = l2 != null ? l2.val : 0;
int sum = n1 + n2 + carry;
if(head == null){
head = tail = new ListNode(sum % 10);
}else{
tail.next = new ListNode(sum % 10);
tail = tail.next;
}
carry = sum / 10;
if(l1 != null){
l1 = l1.next;
}
if(l2 != null){
l2 = l2.next;
}
}
//如到最后还有进位就再增加一个节点
if(carry > 0){
tail.next = new ListNode(carry);
}
return head;
}
}
需要注意的:
"短链表要补零" 和 "最后进位别忘掉"
19. 删除链表的倒数第 N 个结点
先计算链表长度,再循环得到要删除的前一个节点
java
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
int length = getLength(head);
if(length == n)return head.next;
ListNode curr = head;
for(int i = 1;i < length - n;i++){
curr = curr.next;
}
curr.next = curr.next.next;
return head;
}
private int getLength(ListNode head){
int length = 0;
while(head != null){
length++;
head = head.next;
}
return length;
}
}
要注意for(int i = 1;i < length - n;i++)的范围,以防指向null
24. 两两交换链表中的节点
java
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode tempHead = new ListNode(0,head);
ListNode temp = tempHead;
while(temp.next != null && temp.next.next != null){
ListNode l = temp.next;
ListNode r = temp.next.next;
temp.next = r;
l.next = r.next;
r.next = l;
temp = l;
}
return tempHead.next;//不能return head 因为head还是指向以前的头结点
}
}
temp停在当前处理节点的前一个位,l和r分别是temp的后面第1个和后面第2个(即待处理的两位节点)
92.反转链表II

为了应对left=1这一特殊情况,还需要在链表前加一个哨兵节点
java
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverseBetween(ListNode head, int left, int right) {
ListNode dummy = new ListNode(0,head);
ListNode p0 = dummy;
// 找到要反转部分的前一个
for(int i=0;i<left-1;i++){
p0 = p0.next;
}
// 反转要反转的部分
ListNode pre = null,curr = p0.next;
for(int i = 0;i<right-left+1;i++){
ListNode nxt = curr.next;
curr.next = pre;
pre = curr;
curr = nxt;
}
p0.next.next = curr;
p0.next = pre;
return dummy.next;
}
}
25. K 个一组翻转链表

java
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
// 统计节点个数
int n = 0;
for (ListNode cur = head; cur != null; cur = cur.next) {
n++;
}
ListNode dummy = new ListNode(0, head);
ListNode p0 = dummy;
ListNode pre = null;
ListNode cur = head;
// k 个一组处理
for (; n >= k; n -= k) {
for (int i = 0; i < k; i++) { // 同 92 题
ListNode nxt = cur.next;
cur.next = pre; // 每次循环只修改一个 next,方便大家理解
pre = cur;
cur = nxt;
}
// 见视频
ListNode nxt = p0.next;
p0.next.next = cur;
p0.next = pre;
p0 = nxt;
}
return dummy.next;
}
}